먼저 스프링에서 AOP를 구현하는 방법은 3가지 입니다.
1. xml을 이용한 방법
2. Annotaion을 이용한 방법
3. AOP API를 이용하는 방법(요즘 이용도가 떨어짐)
저는 xml을 이용한 방법과 Annotation을 이용한 방법을 포스팅 해보겠습니다.
web.xml 설정
ApplicationContext 빈 설정
1 2 3 4 | <context-param> <param-name>contextConfigLocation</param-name> <!--빈 설정 파일들간에 구분은 줄바꿈(\n),컴마(,),세미콜론(;)등으로 한다.--> <param-value>classpath*:spring/*-context.xml</param-value> </context-param> |
그리고 transaction-context.xml 파일을 생성하였습니다.
1 2 | <!--?XML:NAMESPACE PREFIX = "[default] http://www.springframework.org/schema/beans" NS = "http://www.springframework.org/schema/beans" /--><beans xmlns= "http://www.springframework.org/schema/beans" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:aop= "http://www.springframework.org/schema/aop" xmlns:context= "http://www.springframework.org/schema/context" xmlns:tx= "http://www.springframework.org/schema/tx" xsi:schemalocation= "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" > </beans> |
1 2 3 4 | <!--?xml:namespace prefix = "context" /--><context:component-scan base-package= "lee" > <context:include-filter type= "annotation" expression= "org.springframework.stereotype.Service" ></context:include-filter> <context:include-filter type= "annotation" expression= "org.springframework.stereotype.Repository" ></context:include-filter> </context:component-scan> |
1 2 3 | <bean class= "lee.test.spring.aop.XmlAopTest" id= "aopTest" ><aop:config><aop:aspect ref= "aopTest" ><aop:pointcut id= "xmlPointCut" expression= "execution(* lee..*Impl.*(..))" ><aop:around pointcut-ref= "xmlPointCut" method= "aroundAOP" ><aop:before pointcut-ref= "xmlPointCut" method= "breforeAOP" ><aop:after pointcut-ref= "xmlPointCut" method= "afterAOP" ><aop:after-returning pointcut-ref= "xmlPointCut" method= "afterReturningAOP" returning= "retValue" ><aop:after-throwing pointcut-ref= "xmlPointCut" method= "afterThrowing" throwing= "ex" > <!-- Advice : E --> </aop:after-throwing></aop:after-returning></aop:after></aop:before></aop:around></aop:pointcut></aop:aspect> </aop:config></bean> |
execution(수식어패턴(생략가능) 리턴타입패턴 패키지패턴.클래스명패턴.메소드명패턴(argument 패턴)
ex).
execution(public * com.ktds.shk..*(..))"
실행( public 메소드이고 모든 Return Type을 가지는 com.ktds.shk. 패키지 아래의 모든 메소드.)
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | package lee.test.spring.aop; import java.util.Arrays; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; public class XmlAopTest { public void breforeAOP(JoinPoint joinPoint){ System.out.println( "----------------------XML-----------breforeAOP" ); Class clazz = joinPoint.getTarget().getClass(); String className = joinPoint.getTarget().getClass().getSimpleName(); String methodName = joinPoint.getSignature().getName(); String classAndMethod = joinPoint.getSignature().toShortString(); System.out.println( "#########clazz######========" + joinPoint.getTarget().getClass()); System.out.println( "########joinPoint.getTarget()#######========" + joinPoint.getTarget()); System.out.println( "########className#######========" + className); System.out.println( "#########methodName######========" + methodName); System.out.println( "##########joinPoint.toLongString()#####========" + joinPoint.toLongString()); System.out.println( "##########joinPoint.toShortString()#####========" + joinPoint.toShortString()); System.out.println( "##########classAndMethod#####========" + classAndMethod); } public Object aroundAOP(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println( "----------------------XML----함수진입------aroundAOP" ); long start = System.nanoTime(); try { System.out.println( "----------------------XML----해당 메소드 실행 전------aroundAOP" ); Object result = joinPoint.proceed(); // 대상객체의 메서드 실행(ProceedingJoinPoint 타입은 대상 객체의 메서드를 호출할 때 사용) return result; } finally { System.out.println( "----------------------XML----해당 메소드 실행 후------aroundAOP" ); long finish = System.nanoTime(); //1/1000000000 Signature sig = joinPoint.getSignature(); //메서드의 시그니쳐 System.out.printf( "%s.%s(%s) 실행 시간 : %d ns\n" , joinPoint.getTarget().getClass().getSimpleName(), sig.getName(), Arrays.toString(joinPoint.getArgs()), (finish - start)/1000000000); System.out.println( "##############joinPoint.toLongString()===================" + joinPoint.toLongString()); //대상 메서드 전체 syntax 리턴 //execution(public abstract javax.sql.DataSource com.ibatis.sqlmap.client.SqlMapTransactionManager.getDataSource()) System.out.println( "##############joinPoint.toShortString()===================" + joinPoint.toShortString()); // 대상 메소드명 리턴 //execution(SqlMapTransactionManager.getDataSource()) System.out.println( "##############joinPoint.getTarget()===================" + joinPoint.getTarget()); //대상객체를 리턴 //com.ibatis.sqlmap.engine.impl.SqlMapClientImpl@1dc7b3e System.out.println( "##############joinPoint.getSignature()===================" + joinPoint.getSignature()); //호출되는 메소드 정보 //DataSource com.ibatis.sqlmap.client.SqlMapTransactionManager.getDataSource() System.out.println( "##############joinPoint.getTarget().getClass().getSimpleName()===================" + joinPoint.getTarget().getClass().getSimpleName()); //SqlMapClientImpl } } public void afterAOP(){ System.out.println( "----------------------XML----------afterAOP" ); } //JoinPoint 는 대상 target 객체 정보를 보유한 결합지점 //retValue 는 target 메서드가 실행한 후 return 값 public void afterReturningAOP(JoinPoint joinPoint, Object retValue){ System.out.println( "---------------XML--------------afterReturningAOP" ); String targetClass=joinPoint.getTarget().getClass().getName(); String methodName=joinPoint.getSignature().getName(); System.out.println( "########logging!! className=" +targetClass+ " methodName=" +methodName + " retVal : " +retValue); } public void afterThrowing(Throwable ex){ System.out.println(ex.getMessage() + " :############## @AfterThrowing" ); } } |
호출순서!