이번에는 스프링의 핵심 기능 중 하나인 AOP에 대해서 알아보려고한다.
AOP란?
AOP란 OOP(객체지향프로그래밍)의 단점(상속, 위임을통한 구현)을 극복해서 나온 기법으로 공통기능을 핵심로직에 삽입하는 형식의 기법이다. AOP기법에서는 공통기능을 직접 호출하지않고 AOP라이브러리가 알맞게 삽입해준다.
AOP의 주요용어
- Advice - 언제 공통기능을 핵심로직에 적용할 지를 나타낸다. ex) 메서드 호출 전(언제)에 트랜잭션 시작기능(공통기능)을 적용한다.
- Joinpoint - Advice를 적용 가능한 지점을 의미한다. 메서드 호출, 필드 값 변경등이 해당된다.
- Pointcut - Joinpoint의 부분집합으로 실제로 Advice가 적용되는 Joinpoint를 나타낸다. AspectJ를 통해 정의한다.
- Weaving - Advice를 핵심로직코드에 적용하는 것을 나타낸다. 즉 공통기능을 핵심 로직코드에 삽입하는 것이다.
- Aspect - 여러 객체에 적용되는 공통기능(로깅, 트랜잭션, 보안)을 뜻한다.
스프링에서는 자체적으로 프록시 기반의 AOP를 제공하고있다. 따라서, 스프링 AOP는 메서드 호출 Joinpoint만을 제공해준다.
구현 가능한 Advice의 종류
- Before Adivce - 메서드 호출 전에 공통기능을 실행
- After Returning Advice - 대상 객체의 메서드가 익셉션 없이 실행 된 후 공통기능을 실행
- After Throwing Advice - 대상 객체의 메서드를 실행하는 도중 익셉션이 발생한 경우 공통기능을 실행
- After Advice - 익셉션이 발생된 여부와 관계 없이 메서드가 실행 된 후에 공통기능을 실행(finally 구문)
- Around Advice - 대상 객체의 메서드 실행 전과 후, 익셉션 발생 시점에 공통기능을 실행
XML설정을 통한 AOP적용은 <aop:config>, <aop:aspect>, <aop:pointcut>, <aop:around>를 통해 적용한다.
<aop:config>
<aop:aspect id = "aspect1" ref = "빈이름">
<aop:pointcut id = "publicMethod" expression = "public * com.flyscanner.my..*(..))"/>
<aop:around pointcut-ref = "publicMethod" method = "trace"/>
<aop:asepect/>
<aop:config/>
@Aspect 애노테이션을 통해서도 AOP를 설정할 수 있다. @Aspect 애노테이션을 사용하려면 먼저 XML설정에서
<aop:aspectj-autoproxy/>를 설정해야한다.
@Aspect
public class profiler2 {
@Pointcut("execution(public * main.controller..*(..))")
private void publicMethod() {
}
@Around("publicMethod")
public Object trace(ProceedingJoinPoint joinPoint) throws Throwable{
String signatureString = joinPoint.getSignature().toShortString();
System.out.println(signatureString + "실행 전");
long start = System.currentTimeMillis();
try {
Object result = joinPoint.proceed();
return result;
}finally {
long finish = System.currentTimeMillis();
System.out.println(signatureString + "실행 후");
System.out.println("실행 시간 " + (finish-start) + "ms");
}
}
}
JoinPoint 파라미터는 항상 첫번째로 사용해야한다.
하나의 JoinPoint에 여러개의 Advice가 지정될 경우 order속성이나 @Order를 통해서 순서를 지정할 수 있다.
'Spring' 카테고리의 다른 글
Spring(7) - HandlerInterceptor (0) | 2019.04.15 |
---|---|
Spring(6) - 스프링 MVC프로젝트 (0) | 2019.04.12 |
Spring(4) - 빈의 생명주기와 범위 (0) | 2019.04.10 |
Spring(3) - @Autowired, @Resource 사용하기 (0) | 2019.04.09 |
Spring(2) - DI(의존성 주입)이란? (0) | 2019.04.09 |