After Returning Advice의 경우 Core Concern이 정상적으로 끝났을 때 호출되도록 하는 방법이다.
xml에 다른 advice들과 동일한 방법으로 bean 추가 및 DI 설정을 해준다.
<!-- Cross-cutting Concern(보조 업무 로직)을 활용할 경우 -->
<bean id="target" class="spring.aop.entity.NewlecExam" p:kor="1" p:eng="2" p:math="1" p:com="3"/>
<bean id="logAroundAdvice" class="spring.aop.advice.LogAroundAdvice" />
<bean id="logBeforeAdvice" class="spring.aop.advice.LogBeforeAdvice" />
<bean id="logAfterReturningAdvice" class="spring.aop.advice.LogAfterReturningAdvice" />
<bean id="exam" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="target"></property>
<property name="interceptorNames">
<list>
<value>logAroundAdvice</value>
<value>logBeforeAdvice</value>
<value>logAfterReturningAdvice</value>
</list>
</property>
</bean>
추가한 클래스를 생성한다. 이 때 상속받는 클래스는 AfterReturningAdvice이고 afterReturning 메소드를 오버라이드 하면된다.
package spring.aop.advice;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class LogAfterReturningAdvice implements AfterReturningAdvice{
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("returnValue : " + returnValue + " method : " + method.getName());
}
}
마찬가지 방법으로 xml에 설정을 추가한다.
<!-- Cross-cutting Concern(보조 업무 로직)을 활용할 경우 -->
<bean id="target" class="spring.aop.entity.NewlecExam" p:kor="101" p:eng="2" p:math="1" p:com="3"/>
<bean id="logAroundAdvice" class="spring.aop.advice.LogAroundAdvice" />
<bean id="logBeforeAdvice" class="spring.aop.advice.LogBeforeAdvice" />
<bean id="logAfterReturningAdvice" class="spring.aop.advice.LogAfterReturningAdvice" />
<bean id="logAfterThrowingAdvice" class="spring.aop.advice.LogAfterThrowingAdvice" />
<bean id="exam" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="target"></property>
<property name="interceptorNames">
<list>
<value>logAroundAdvice</value>
<value>logBeforeAdvice</value>
<value>logAfterReturningAdvice</value>
<value>logAfterThrowingAdvice</value>
</list>
</property>
</bean>
추가 클래스를 생성하고 ThrowsAdvice 클래스를 상속받는데 이 때 오버라이드를 하는 것이 아닌 직접 메소드를 구현한다. Exception의 경우의 수는 많기 때문이다.
package spring.aop.advice;
import org.springframework.aop.ThrowsAdvice;
public class LogAfterThrowingAdvice implements ThrowsAdvice{
public void afterThrowing(IllegalArgumentException e) throws Throwable {
System.out.println("예외가 발생하였습니다 : " + e.getMessage());
}
}
일부러 Exception 경우에 대해 에러를 던질 수 있도록 코드를 추가한다.
@Override
public int total() {
int result = kor+eng+math+com;
if(kor > 100) {
throw new IllegalArgumentException("유효하지 않은 점수");
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
xml에 kor 값이 101이므로 IllegalArgumentException이 발생하여 구성한대로 동작하는 것을 확인할 수 있다.
실행 결과
먼저 실행될 로직 Exception in thread "main" java.lang.IllegalArgumentException: 유효하지 않은 점수 예외가 발생하였습니다 : 유효하지 않은 점수 at spring.aop.entity.NewlecExam.total(NewlecExam.java:62) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:112) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:55) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:56) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at spring.aop.advice.LogAroundAdvice.invoke(LogAroundAdvice.java:13) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) at com.sun.proxy.$Proxy4.total(Unknown Source) at spring.aop.Program.main(Program.java:25)