스프링

Spring AOP Advice 5가지

코드 죄수 2022. 10. 27. 13:55

before

메서드를 시작하기 전에 먼저 호출이 되어 실행된다.

 

after

메서드가 예외로 끝나던 정상적으로 끝나던 기능이 완료 되면 호출되어 실행된다.

 

after - returning

메서드가 예외없이 정상적으로 잘 끝나면 호출되어 실행된다.

 

after - throwing

메서드 실행 도중 예외 발생 시 호출되어 실행된다.

 

around

메소드 실행 전/후 및 예외 발생시 호출되어 실행된다.

 

 

 

 

xml 적용 시

<bean id="logAop" class="com.example.aop.LogAop"/>

 <aop:config>
 		<!--before-->
        <aop:aspect id="logger" ref="logAop">
            <aop:pointcut id="publicM" expression="within(com.example.aop.*)"/>
            <aop:before method="beforeAdvice" pointcut-ref="publicM" />
        </aop:aspect>

		<!--after-returning-->
        <aop:aspect id="logger" ref="logAop">
            <aop:pointcut id="publicM" expression="within(com.example.aop.*)"/>
            <aop:after-returning method="afterReturningAdvice" pointcut-ref="publicM" />
        </aop:aspect>

		<!--after-throwing-->
        <aop:aspect id="logger" ref="logAop">
            <aop:pointcut id="publicM" expression="within(com.example.aop.*)"/>
            <aop:after-throwing method="afterThrowingAdvice" pointcut-ref="publicM" />
        </aop:aspect>

		<!--after-->
        <aop:aspect id="logger" ref="logAop">
            <aop:pointcut id="publicM" expression="within(com.example.aop.*)"/>
            <aop:after method="afterAdvice" pointcut-ref="publicM" />
        </aop:aspect>

		<!--around-->
        <aop:aspect id="logger" ref="logAop">
            <aop:pointcut id="publicM" expression="within(com.example.aop.*)"/>
            <aop:around pointcut-ref="publicM" method="loggerAop"/>
        </aop:aspect>
    </aop:config>

 

LogAop.java

public class LogAop {

    public Object loggerAop(ProceedingJoinPoint jointPoint) throws Throwable {
        String signatureStr = jointPoint.getSignature().toShortString();
        System.out.println(signatureStr + "is start.");
        long st = System.currentTimeMillis();

        try{
            Object obj = jointPoint.proceed();  //핵심 기능 호출
            return obj;
        }finally {
            long et = System.currentTimeMillis();
            System.out.println(signatureStr + "is finished.");
            System.out.println(signatureStr + "경과시간: " + (et - st));
        }
    }

    public void beforeAdvice(JoinPoint joinPoint){
        System.out.println("beforeAdvice()");
    }
    public void afterAdvice(){
        System.out.println("afterAdvice()");
    }
    public void afterThrowingAdvice(){
        System.out.println("afterThrowingAdvice()");
    }
    public void afterReturningAdvice(){
        System.out.println("afterReturningAdvice()");
    }
}

결과 화면

Advice 기능은 우선순위를 줄 수 있는데 현재 우선순위를 주지 않았기 때문에 같은 우선순위를 가지고 있다.

 

같은 우선순위면 코드상 위쪽에 있는 기능이 우선순위를 가지게 됨으로 

 

결과 화면을 보면 before이 around보다 먼저 실행된 모습을 볼 수 있다.

 

하지만 핵심기능이 끝난 이후로 보면 오히려 around가 코드상 위쪽에 있는 after보다 먼저 실행된 모습을 볼 수 있다.

 

그 이유는 핵심기능이 전에 실행되는 기능들은 우선순위가 높은 순으로 실행되지만

 

핵심기능 이후에 실행되는 기능들은 오히려 우선순위가 낮은 순으로 실행되기 때문이다.