2013년 10월 21일 월요일

[Spring AOP Annoatation 강좌]Spring3.X AOP + AspectJ annotation 예제[스프링3.X AspectJ,애노테이션예제] 스프링3.2에서 간단하게 작성된 예제

[Spring AOP Annoatation 강좌]Spring3.X AOP + AspectJ annotation 예제[스프링3.X AspectJ,애노테이션예제]  

스프링3.2에서 간단하게 작성된 예제이니 Spring의 AOP, 충고(Advice), 교차점(Pointcut), 애스팩트(Aspect), 애노테이션(Annotation)에 대해 예제를 통해 이해 하도록 하세요.
 
 
package onj.aspectj.annotation;
/**
 * 오라클자바커뮤니티, 오엔제이프로그래밍실무교육센터
 * www.onjprogramming.co.kr
 * Spring3.X AOP Annotation example
 */
public interface Emp {
void addEmp();
String addEmpReturnVal();
String addEmpAround(String name);
void addEmpThrowException() throws Exception;
}



package onj.aspectj.annotation;

/**
 * 오라클자바커뮤니티, 오엔제이프로그래밍실무교육센터
 * www.onjprogramming.co.kr
 * Spring3.X AOP Annotation example
 */
public class EmpImpl implements Emp {
public void addEmp() {
System.out.println("exec addEmp()...");
}
public String addEmpReturnVal() {
System.out.println("exec addEmpReturnVal()...");
return "addEmpReturnVal()";
}
public String addEmpAround(String name) {
System.out.println("exec addEmpThrowException()...," + name);
return name;
}
public void addEmpThrowException() throws Exception {
System.out.println("exec addEmpThrowException()...");
throw new Exception("Onj Error");
}
}





package onj.aspectj.annotation;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

/**
 * 오라클자바커뮤니티, 오엔제이프로그래밍실무교육센터 www.onjprogramming.co.kr Spring3.X AOP Annotation
 * example
 */
@Aspect
public class LoggingAspect {

// 사전충고:메소드 실행전 충고 실행
@Before("execution(* onj.aspectj.annotation.Emp.addEmp(..))")
// 포인트컷
public void logBefore(JoinPoint joinPoint) {
System.out.println("Advice --> logBefore()...");
joinPoint.getSignature().getName();
}

// 사후충고:오류가 나더라도 메소드 호출 후 실행
@After("execution(* onj.aspectj.annotation.Emp.addEmp(..))")
// 포인트컷
public void logAfter(JoinPoint joinPoint) {
System.out.println("Advice --> logAfter()...");
joinPoint.getSignature().getName();
}

// 사후충고(after returning) : 반드시 정상 리턴되야지...
// returning 속성으로 리턴값을 받을 수 있다.
@AfterReturning(pointcut = "execution(* onj.aspectj.annotation.Emp.addEmpReturnVal(..))", returning = "result")
public void logAfterReturning(JoinPoint joinPoint, Object result) {
System.out.println("Advice --> logAfterReturning()...");
joinPoint.getSignature().getName();
System.out.println("return value is " + result);
}

// 주변충고
@Around("execution (* onj.aspectj.annotation.Emp.addEmpAround(..))")
public String logAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Advice --> logAround()...");
joinPoint.getSignature().getName();
Arrays.toString(joinPoint.getArgs());
System.out.println("Around before is running!");
String s = (String)joinPoint.proceed(); // 타겟 객체의 원본 메소드 실행
System.out.println("Around after is running!");
//return문으로 인해 원래 Target의 메소드의 리턴을 대체!!
//원래 정상적인 경우라면 오엔제이프로그래밍실무교육센터가 리턴됨
return "이문장으로원래 타겟메소드(addEmpAround) 리턴이 대체됨!!";  
}

// 예외충고:예외가 발생될때 충고 실행
@AfterThrowing(pointcut = "execution (* onj.aspectj.annotation.Emp.addEmpThrowException(..))", throwing = "error")
// error는 실행되는 메소드에서 던져지는 예외
public void logAfterThrowing(JoinPoint joinPoint, Throwable error) {
System.out.println("Advice --> logAfterThrowing()...");
joinPoint.getSignature().getName();
System.out.println("Exception " + error);
}
}





package onj.aspectj.annotation;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 오라클자바커뮤니티, 오엔제이프로그래밍실무교육센터
 * www.onjprogramming.co.kr
 * Spring3.X AOP Annotation example
 */
public class AspectJAnnotationExam {
public static void main(String[] args) throws Exception{
ApplicationContext ctx = new ClassPathXmlApplicationContext("aspectjannotation.xml");
Emp e = (Emp)ctx.getBean("emp");
//사전, 사후중고
e.addEmp();
//사후충고(after returning)
e.addEmpReturnVal();
//주변충고
String s = e.addEmpAround("오엔제이프로그래밍실무교육센터");
System.out.println(s);
//예외충고
e.addEmpThrowException();
}
}
 
 
 
aspectjannotation.xml
 
<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"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-3.2.xsd ">

 <aop:aspectj-autoproxy />

 <bean id="emp" class="onj.aspectj.annotation.EmpImpl" />

 <bean id="myLogger" class="onj.aspectj.annotation.LoggingAspect" />

</beans>




[결과]
INFO : org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@152506e: startup date [Wed Oct 02 21:33:52 KST 2013]; root of context hierarchy
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [aspectjannotation.xml]
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@203a16: defining beans [org.springframework.aop.config.internalAutoProxyCreator,emp,myLogger]; root of factory hierarchy
Advice --> logBefore()...
exec addEmp()...
Advice --> logAfter()...
exec addEmpReturnVal()...
Advice --> logAfterReturning()...
return value is addEmpReturnVal()
Advice --> logAround()...
Around before is running!
exec addEmpThrowException()...,오엔제이프로그래밍실무교육센터
Around after is running!
이문장으로원래 타겟메소드(addEmpAround) 리턴이 대체됨!!
Exception in thread "main" exec addEmpThrowException()...
Advice --> logAfterThrowing()...
Exception java.lang.Exception: Onj Error
java.lang.Exception: Onj Error
at onj.aspectj.annotation.EmpImpl.addEmpThrowException(EmpImpl.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:55)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy9.addEmpThrowException(Unknown Source)
at onj.aspectj.annotation.AspectJAnnotationExam.main(AspectJAnnotationExam.java:28)




댓글 없음:

댓글 쓰기