Invoke Method Start....
12월 26, 2013 3:55:58 오후 AOP.LogPrintHandler invoke
정보: 타이머 시작
12월 26, 2013 3:55:58 오후 AOP.LogPrintHandler invoke
정보: 타이머 정지
12월 26, 2013 3:55:58 오후 AOP.LogPrintHandler invoke
정보: [TimeLOG] Method : ADD
12월 26, 2013 3:55:58 오후 AOP.LogPrintHandler invoke
정보: [TimeLOG] process Time : 28
1050
Invoke Method Start....
12월 26, 2013 3:55:58 오후 AOP.LogPrintHandler invoke
정보: 타이머 시작
12월 26, 2013 3:55:58 오후 AOP.LogPrintHandler invoke
정보: 타이머 정지
12월 26, 2013 3:55:58 오후 AOP.LogPrintHandler invoke
정보: [TimeLOG] Method : MUL
12월 26, 2013 3:55:58 오후 AOP.LogPrintHandler invoke
정보: [TimeLOG] process Time : 0
800
12월 26, 2013 4:32:34 오후 org.springframework.context.support.AbstractApplicationContext prepareRefresh
정보: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@40c19080: startup date [Thu Dec 26 16:32:34 KST 2013]; root of context hierarchy
12월 26, 2013 4:32:34 오후 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
정보: Loading XML bean definitions from class path resource [ApplicationContext.xml]
12월 26, 2013 4:32:34 오후 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
정보: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5b43c919: defining beans [cal,logPrintAroundAdvice,proxy]; root of factory hierarchy
Invoke Method Start
12월 26, 2013 4:32:35 오후 AOP2.LogPrintAroundAdvice invoke
정보: 타이머 시작
12월 26, 2013 4:32:35 오후 AOP2.LogPrintAroundAdvice invoke
정보: 타이머 정지
12월 26, 2013 4:32:35 오후 AOP2.LogPrintAroundAdvice invoke
정보: [TimeLOG] Method : public abstract int AOP2.Calc.ADD(int,int)
12월 26, 2013 4:32:35 오후 AOP2.LogPrintAroundAdvice invoke
정보: [TimeLOG] process Time : 1
800
Invoke Method Start
12월 26, 2013 4:32:35 오후 AOP2.LogPrintAroundAdvice invoke
정보: 타이머 시작
12월 26, 2013 4:32:35 오후 AOP2.LogPrintAroundAdvice invoke
정보: 타이머 정지
12월 26, 2013 4:32:35 오후 AOP2.LogPrintAroundAdvice invoke
정보: [TimeLOG] Method : public abstract int AOP2.Calc.MUL(int,int)
12월 26, 2013 4:32:35 오후 AOP2.LogPrintAroundAdvice invoke
정보: [TimeLOG] process Time : 1
150000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package AOP3;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.MethodBeforeAdvice;
public class LogPrintBeforeAdvice implements MethodBeforeAdvice {
//Advice 중에서 이전 적용 되는 인터페이스 : MethodBeforeAdvice
@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
System.out.println("Before Method Start");
Log log = LogFactory.getLog(this.getClass());
//StopWatch sw = new StopWatch();
//sw.start();
log.info("[Method Before ]: 이전 보조 업무 시작 ");
}
}
|
그리고 xml 설정 파일에 해당 클래스를 등록시키면 됨
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<?xml version="1.0" encoding="UTF-8"?>
<bean id="cal" class="AOP3.NewCalc"></bean>
<bean id ="logPrintbeforeAdvice" class="AOP3.LogPrintBeforeAdvice"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>AOP3.Calc</value>
</list>
</property>
<property name="target" ref="cal"></property>
<property name="interceptorNames">
<list>
<value>logPrintbeforeAdvice</value>
</list>
</property>
</bean>
</beans>
|
------------------------------------------------결과값
12월 26, 2013 4:34:58 오후 org.springframework.context.support.AbstractApplicationContext prepareRefresh
정보: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@40c19080: startup date [Thu Dec 26 16:34:58 KST 2013]; root of context hierarchy
12월 26, 2013 4:34:58 오후 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
정보: Loading XML bean definitions from class path resource [ApplicationContext.xml]
12월 26, 2013 4:34:58 오후 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
정보: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5b43c919: defining beans [cal,logPrintbeforeAdvice,proxy]; root of factory hierarchy
Before Method Start
12월 26, 2013 4:34:58 오후 AOP3.LogPrintBeforeAdvice before
정보: [Method Before ]: 이전 보조 업무 시작
800
Before Method Start
150000
12월 26, 2013 4:34:58 오후 AOP3.LogPrintBeforeAdvice before
정보: [Method Before ]: 이전 보조 업무 시작
------------------------------------------------결과값
5. 이번엔 After 기능에 대해서 알아보겠음
4번과 마찬가지로 패키지 생성 (편의상 AOP4로 칭함)
그리고 설정 파일 xml 과 설정 java 파일 을 제외한
나머지 내용을 복사해두고
3개 클래스 이외의 LogPrintAroundAdvice.java 도 가져오도록 함
(해당 내용이 실행되는 시점이 언제인지 확인하기 위해서)
이전 것과 다른점만 확인하기로 함
먼저 AfterReturning.java 파일을 생성하고 다음과 같이 작성함
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
package AOP4;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.AfterReturningAdvice;
public class AfterReturning implements AfterReturningAdvice{
@Override
public void afterReturning(Object returnValue, Method method, Object[] args,
Object target) throws Throwable {
System.out.println("[afterReturning] start...");
Log log = LogFactory.getLog(this.getClass());
log.info("[After MethodName ] " + method.getName() +
" / Return Value : "+ returnValue +
" / args" + Arrays.toString(args));
}
}
|
그리고 xml 파일을 다음과 같이 수정함
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<?xml version="1.0" encoding="UTF-8"?>
<bean id="cal" class="AOP4.NewCalc"></bean>
<bean id ="logPrintAroundAdvice" class="AOP4.LogPrintAroundAdvice"></bean>
<bean id ="afterReturning" class="AOP4.AfterReturning"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>AOP4.Calc</value>
</list>
</property>
<property name="target" ref="cal"></property>
<property name="interceptorNames">
<list>
<value>afterReturning</value>
<value>logPrintAroundAdvice</value>
</list>
</property>
</bean>
</beans>
|
여기선 after 적용시점인지 언제 인지 확인하기 위해 AOP2에서 실습했던
LogPrintAroundAdvice.java 를 가져옴
------------------------------------------------결과값
12월 26, 2013 4:56:06 오후 org.springframework.context.support.AbstractApplicationContext prepareRefresh
정보: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@76bc3ed6: startup date [Thu Dec 26 16:56:06 KST 2013]; root of context hierarchy
12월 26, 2013 4:56:06 오후 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
정보: Loading XML bean definitions from class path resource [ApplicationContext.xml]
12월 26, 2013 4:56:06 오후 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
정보: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@26ffab3f: defining beans [cal,logPrintAroundAdvice,afterReturning,proxy]; root of factory hierarchy
Invoke Method Start
12월 26, 2013 4:56:06 오후 AOP4.LogPrintAroundAdvice invoke
정보: 타이머 시작
12월 26, 2013 4:56:06 오후 AOP4.LogPrintAroundAdvice invoke
정보: 타이머 정지
12월 26, 2013 4:56:06 오후 AOP4.LogPrintAroundAdvice invoke
정보: [TimeLOG] Method : public abstract int AOP4.Calc.ADD(int,int)
12월 26, 2013 4:56:06 오후 AOP4.LogPrintAroundAdvice invoke
정보: [TimeLOG] process Time : 1
[afterReturning] start...
12월 26, 2013 4:56:06 오후 AOP4.AfterReturning afterReturning
정보: [After MethodName ] ADD / Return Value : 800 / args[500, 300]
800
Invoke Method Start
12월 26, 2013 4:56:06 오후 AOP4.LogPrintAroundAdvice invoke
정보: 타이머 시작
12월 26, 2013 4:56:06 오후 AOP4.LogPrintAroundAdvice invoke
정보: 타이머 정지
12월 26, 2013 4:56:06 오후 AOP4.LogPrintAroundAdvice invoke
정보: [TimeLOG] Method : public abstract int AOP4.Calc.MUL(int,int)
12월 26, 2013 4:56:06 오후 AOP4.LogPrintAroundAdvice invoke
정보: [TimeLOG] process Time : 0
[afterReturning] start...
12월 26, 2013 4:56:06 오후 AOP4.AfterReturning afterReturning
정보: [After MethodName ] MUL / Return Value : 150000 / args[500, 300]
150000
------------------------------------------------결과값
6. Advice 의 throw 발생시 실행되는 advice 를 구현하도록 함
새로운 패키지를 만드는데 편의상 AOP5 라고 명칭하고 해당 밑에
이전에 사용했던 클래스들을 복사해 둠
그리고 LogPrintAfterThrowingAdvice.java 및 xml 을 아래와 같이 수정함
1
2
3
4
5
6
7
8
9
10
|
package AOP5;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.ThrowsAdvice;
public class LogPrintAfterThrowingAdvice implements ThrowsAdvice{
public void afterThrowing(IllegalArgumentException e) throws Throwable{
Log log = LogFactory.getLog(this.getClass());
log.info("[After Throwing 예외발생] : " + e.getMessage());
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?xml version="1.0" encoding="UTF-8"?>
<bean id="cal" class="AOP5.NewCalc"></bean>
<bean id ="logPrintAfterThrowingAdvice" class="AOP5.LogPrintAfterThrowingAdvice"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>AOP5.Calc</value>
</list>
</property>
<property name="target" ref="cal"></property>
<property name="interceptorNames">
<list>
<value>logPrintAfterThrowingAdvice</value>
</list>
</property>
</bean>
</beans>
|
------------------------------------------------결과값
정보: [After Throwing 예외발생] : Y값이 X값보다 큽니다.
Exception in thread "main" java.lang.IllegalArgumentException: Y값이 X값보다 큽니다.
at AOP5.NewCalc.SUB(NewCalc.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy0.SUB(Unknown Source)
at AOP5.CalcMain.main(CalcMain.java:33)
------------------------------------------------결과값
7. 설정된 advice 중에서 PointCut 을 구현
PointCut는 advice는 설정된 클래스에 포함된 전체 함수를
다 실행하는걸 기본으로 알고 있는데
PointCut 을 설정해두면 설정한 클래스에서 실행할 함수를
골라서 쓸수 있는 장점이 있음
우선 패키지를 하나 만들고(편의상 AOP6으로 칭한다.)
main, 인터페이스, 인터페이스 상속받은거 , LogPrintAroundAdvice.java
네개는 복사해둔다.
여기서는 순수하게 ApplicationContext.xml 설정만 정리하면 가능하다
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
<?xml version="1.0" encoding="UTF-8"?>
<bean id="cal" class="AOP6.NewCalc"></bean>
<bean id ="logPrintAroundAdvice" class="AOP6.LogPrintAroundAdvice"></bean>
<bean id ="logPrintbeforeAdvice" class="AOP6.LogPrintBeforeAdvice"></bean>
<bean id ="afterReturning" class="AOP6.AfterReturning"></bean>
<bean id ="logPrintAfterThrowingAdvice" class="AOP6.LogPrintAfterThrowingAdvice"></bean>
<!-- ************PointCut으로 설정하기******************************** -->
<bean id="nameMatchMethodPointcut"
class="org.springframework.aop.support.NameMatchMethodPointcut">
<!-- 여러 함수를 같이 pointcut 할때 쓰는 경우 -->
<property name="mappedNames" >
<list>
<value>ADD</value>
<value>MUL</value>
</list>
</property>
</bean>
<!-- ************Advisor 함수 이름으로 설정하기************************************* -->
<bean id="defaultPointcutAdvisor"
class="org.springframework.aop.support.DefaultPointcutAdvisor">
<!-- 사용할 PointCut 은 무엇이고 -->
<property name="pointcut" ref= "nameMatchMethodPointcut"></property>
<!-- 어떤 advice를 포인트에 연결할 것인지를 결정 -->
<property name="advice" ref="logPrintAroundAdvice"></property>
</bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>AOP6.Calc</value>
</list>
</property>
<property name="target" ref="cal"></property>
<property name="interceptorNames">
<list>
<value>logPrintbeforeAdvice</value>
<value>afterReturning</value>
<value>logPrintAfterThrowingAdvice</value> -->
<value>defaultPointcutAdvisor</value>
</list>
</property>
</bean>
</beans>
|
------------------------------------------------결과값
12월 26, 2013 5:31:06 오후 org.springframework.context.support.AbstractApplicationContext prepareRefresh
정보: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@40c19080: startup date [Thu Dec 26 17:31:06 KST 2013]; root of context hierarchy
12월 26, 2013 5:31:06 오후 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
정보: Loading XML bean definitions from class path resource [ApplicationContext.xml]
12월 26, 2013 5:31:07 오후 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
정보: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5b43c919: defining beans [cal,logPrintAroundAdvice,logPrintbeforeAdvice,afterReturning,logPrintAfterThrowingAdvice,nameMatchMethodPointcut,defaultPointcutAdvisor,proxy]; root of factory hierarchy
-20
Invoke Method Start
12월 26, 2013 5:31:07 오후 AOP6.LogPrintAroundAdvice invoke
정보: 타이머 시작
12월 26, 2013 5:31:07 오후 AOP6.LogPrintAroundAdvice invoke
정보: 타이머 정지
12월 26, 2013 5:31:07 오후 AOP6.LogPrintAroundAdvice invoke
정보: [TimeLOG] Method : public abstract int AOP6.Calc.ADD(int,int)
12월 26, 2013 5:31:07 오후 AOP6.LogPrintAroundAdvice invoke
정보: [TimeLOG] process Time : 1
800
Invoke Method Start
12월 26, 2013 5:31:07 오후 AOP6.LogPrintAroundAdvice invoke
정보: 타이머 시작
12월 26, 2013 5:31:07 오후 AOP6.LogPrintAroundAdvice invoke
정보: 타이머 정지
12월 26, 2013 5:31:07 오후 AOP6.LogPrintAroundAdvice invoke
정보: [TimeLOG] Method : public abstract int AOP6.Calc.MUL(int,int)
12월 26, 2013 5:31:07 오후 AOP6.LogPrintAroundAdvice invoke
정보: [TimeLOG] process Time : 1
150000
------------------------------------------------결과값
8. 추가적으로 7번 xml 설정 파일에서
1
2
3
4
5
6
7
8
9
10
11
|
<!-- ************PointCut으로 설정하기******************************** -->
<bean id="nameMatchMethodPointcut"
class="org.springframework.aop.support.NameMatchMethodPointcut">
<!-- 여러 함수를 같이 pointcut 할때 쓰는 경우 -->
<property name="mappedNames" >
<list>
<value>ADD</value>
<value>MUL</value>
</list>
</property>
</bean>
|
이 부분을 다음과 같이 치환 가능하다.
(1) 하나의 함수를 실행하면 되는 경우
1
2
3
|
<bean id="nameMatchMethodPointcut"
class="org.springframework.aop.support.NameMatchMethodPointcut">
<property name="mappedNames" value="ADD"></property>
|
(2) 조건식(정규식) 을 이용하고자 하는 경우
1
2
3
4
5
6
7
8
9
10
|
<bean id="regexpMethodPointcutAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="patterns" >
<list>
<value>.*AD.*</value>
<value>.*L</value>
</list>
</property>
<property name="advice" ref="logPrintAroundAdvice"></property>
</bean>
|