웹/spring
[spring] AOP (Aspect Oriented Programming)
은은하게미친자
2022. 8. 25. 11:26
728x90
AOP (Aspect Oriented Programming)
: 관점 지향 프로그래밍, 어떤 로직을 기준으로 핵심적인/부가적인 관점을 나누어서 보고 그 관점을 기준으로 각각 모듈화 하는 것.
주로 로깅, 트랜잭션 관리, 에러처리 등 비즈니스단의 메소드를 조금더 세밀하게 조정하고싶을때 사용.
AOP는 핵심 모듈 사이에 필욯나 기능을 삽입하여 적절한 타이밍에 호출 되도록 해주는 기능.
이를 구현할때 스프링은 대상 빈을 프록시로 감싸는 방법을 사용합니다.
프록시?
어떠한 빈 (클래스)가 AOP대상이면 원본 클래스 대신 프록시가 감싸진 클래스가 자동으로 만들어져 프록시 클래스가 빈에 등록이 도비니다. 이렇게 빈에 등록된 프록시 클래스는 원본 클래스가 호출되면서 자동으로 바꿔서 사용해줍니다.
주요 개념
- Aspect : 흩어진 관심사(Crosscutting Concerns), 즉핵심업무를 모듈화한것
- Target : Aspect를 적용하는 곳 (클랫, 메서드)
- Advice : 어떤일을 해야 할 지에 대한것, 실직적인 부가 기능을 담은 구현체
- JoinPoint : Advice가 적용될 위치 ex ) 끼어들수있는 지점, 메서드 진입지점, 생성자 호출 지점 등
- PointCut : JointPoint의 상세한 스펙을 정의한것, 구체적인 Advice 실행지점을 정할 수있음.
- Weaving : AOP에서 joinpoint들을 advice로 감싸는 과정이다. 이작업을 도와주는것이 AspectJ등의 AOP툴이 하는 역할이다.
AOP 주요 애너테이션 및 포인트컷
@Component | 스프링 context에 빈으로등록 , <Bean class=“…”/> 와 같은표현 |
@Aspect | @Aspect 임을 명시 |
@Around("${pattern}") | 지정된 패턴에 해당하는 메소드의 실행 전/후에 동작 지정된 메소드의 반환값: Object (지정된 패턴에 해당하는 메소드의 실행 결과를 반환해야 하므로) pointcut 표현식의 패턴이 들어간다. ex)) @Around("execution(* kr.co.dong.controller.*Controller.*(..))") |
@Before("${pattern}") | 지정한 패턴에 해당하는 메소드가 실행 되기전에 , interceptor와 같이 동작 지정된 메소드의 반환값 : void |
@After("${pattern}") | 지정한 패턴에 해당하는 메소드가 실행된 후에 동작 지정된 메소드의 반환값 : void |
@AfterReturning() | 해당하는 메소드가 정상적인 수행 후 |
@AfterThrowing() | 예외발생후 |
+ Pointcut 표현식
- * : ALL
- (..) : 0개이상
- *Controller.*(..) : 모든 컨트롤러 하위에 있는 모든 메서드 중 인자가 0개이상인 모든것.
적용해보기
1. pom.xml에 aspectj 셋업 확인하기
aspectj 버전확인하기 | <org.aspectj-version>1.8.9</org.aspectj-version> | |||
aspectjweaver 추가 |
|
|||
maven update 하기 |
2. servlet-context.xml
aop, tx 설정 체크하고 저장하기
aspectj 자동 프록시 태그 추가하기 |
|
3. 구현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package kr.co.dong.commom;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component //스프링 context에 빈으로등록
@Aspect //@Aspect 명시
public class LoggerAspect {
protected Logger log = LoggerFactory.getLogger(LoggerAspect.class);
@Around("execution(* kr.co.dong.controller.*Controller.*(..))")
public Object logPrint(ProceedingJoinPoint joinpoint) throws Throwable {
Object result = null;
long start = System.currentTimeMillis();
result = joinpoint.proceed();
long end = System.currentTimeMillis();
log.info(String.format("수행시간 : %dms %n", (end-start)));
return result;
}
}
|
cs |
4. 정상처리시
728x90