2014년 5월 7일 수요일

[오라클자바커뮤니티]spring framework3/4 @AspectJ annotation 애노테이션을 이용한 AOP구현예제(Spring Framework3.X AOP구현하기,Advice, Pointcut, Aspect) ​

[오라클자바커뮤니티]spring framework3/4 @AspectJ annotation 애노테이션을 이용한 AOP구현예제(Spring Framework3.X AOP구현하기,Advice, Pointcut, Aspect)


- 다음과 같은 인터페이스와 타겟 클레스가 있다. 

package onj.aop.aspectjannotation;

interface OnjWorld {
public void onjHello();
public void onjHello2() throws Exception;
}

package onj.aop.aspectjannotation;
//Target Class
public class OnjWorldImpl implements OnjWorld {
public void onjHello() {
System.out.println("OnJ에오신것을 환영합니다.");
}

public void onjHello2() throws Exception {
System.out.println("OnJ2에오신것을 환영합니다.");
throw new Exception("OnJ Exception...");
}
}

위 OnjWorldImpl이 타겟 클래스이다. onjHello2 로 시작하는 메소드에 스프링 충고를 내릴려고 한다. 
충고(Advice)는 적당히 콘솔화면에 출력하는 정도로 만들고... 
before advice, around advice, throws advice, after,after returning advice를 구현하시오. 

- @AspectJ Annotation을 이용하여 구현해 보았다.

가장 핵심이 되는 클래스는 Aspect인 AonjLoggingAspect이다. 그안에 충고, 포인트컷에 대한 AspectJ 표현식등이 기술되어 Aspect(Advice + PointCut)를   만든다.

1. OnjWorld.java

package onj.aop.aspectjannotation;

interface OnjWorld {
public void onjHello();
public void onjHello2() throws Exception;
}

2. OnjWorldImpl.java

package onj.aop.aspectjannotation;

public class OnjWorldImpl implements OnjWorld {
public void onjHello() {
System.out.println("OnJ에오신것을 환영합니다.");
}

public void onjHello2() throws Exception {
System.out.println("OnJ2에오신것을 환영합니다.");
throw new Exception("OnJ Exception...");
}
}


3.  OnjLoggingAspect.java

package onj.aop.aspectjannotation;

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;

@Aspect
public class OnjLoggingAspect {
 //사전충고(Before Advice)
 @Before("execution (* onj.aop.aspectjannotation.OnjWorld.onjHello(..))")
 public void logBefore(JoinPoint joinPoint){
  System.out.println("<<<<< Advice-->logBefore()...");
  joinPoint.getSignature().getName();
 }
 
 //사후중고(After Advice), 타겟메소드 실행 후 즉시 실행
 @After("execution (* onj.aop.aspectjannotation.OnjWorld.onjHello(..))")
 public void logAfter(JoinPoint joinPoint){
  System.out.println("<<<<< Advice --> logAfter()...");
  joinPoint.getSignature().getName();
 }
 
 //사후중고(After Returnning Advice), 타겟메소드 리턴 후 실행
 @AfterReturning(pointcut = "execution (* onj.aop.aspectjannotation.OnjWorld.onjHello(..))", 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 Advice), 타겟메소드 실행전, 리턴 후 두번 충고 실행 
 @Around("execution (* onj.aop.aspectjannotation.OnjWorld.onjHello(..))")
 public String logAround(ProceedingJoinPoint joinPoint) throws Throwable{
  System.out.println("<<<<< Advice --> logAournd()...");
  joinPoint.getSignature().getName();
  Arrays.toString(joinPoint.getArgs());
  System.out.println("<<<<< Around before is renning!");
  joinPoint.proceed();
  System.out.println("<<<<< Around after is renning!)");
  return "이 문장으로 원래 타겟메소드 리턴이 대체됨!";
 }
 
 //예외충고(Throws Advice), 예외가 발생했을 때 예외전에 충고실행
 @AfterThrowing(pointcut = "execution (* onj.aop.aspectjannotation.OnjWorld.onjHello2(..))", throwing = "error")
 public void logAfterThrowing(JoinPoint joinPoint, Throwable error){
  System.out.println("<<<<< Advice --> logAfterThrowing()...");
  joinPoint.getSignature().getName();
  System.out.println("<<<<< Exception " +error);
 }
}


4. OnjClient.java

package onj.aop.aspectjannotation;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class OnjClient {
 public static void main(String[] args) throws Exception{
  ApplicationContext ctx =new ClassPathXmlApplicationContext("aspectjannotation.xml"); 
  
  OnjWorld o = (OnjWorld)ctx.getBean("onjWorld");
  
  o.onjHello();
  o.onjHello2();
 }
}



5. src/main/resource/aspectjannotation.xml

<?xml version="1.0" encoding="UTF-8"?>
<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="onjWorld" class="onj.aop.aspectjannotation.OnjWorldImpl" />
 <bean id="onjLogger" class="onj.aop.aspectjannotation.OnjLoggingAspect" />
 
</beans>


6.[결과]

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/java/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Documents%20and%20Settings/Administrator/.m2/repository/org/slf4j/slf4j-log4j12/1.6.6/slf4j-log4j12-1.6.6.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
INFO : org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6250d2: startup date [Tue Feb 04 07:20:40 KST 2014]; 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@1518883: defining beans [org.springframework.aop.config.internalAutoProxyCreator,onjWorld,onjLogger]; root of factory hierarchy
<<<<< Advice --> logAournd()...
<<<<< Around before is renning!
<<<<< Advice-->logBefore()...
OnJ에오신것을 환영합니다.
<<<<< Around after is renning!)
<<<<< Advice --> logAfter()...
<<<<< Advice --> logAfterReturning()...
<<<<< return value is 이 문장으로 원래 타겟메소드 리턴이 대체됨!
OnJ2에오신것을 환영합니다.
<<<<< Advice --> logAfterThrowing()...
<<<<< Exception java.lang.Exception: OnJ Exception...
Exception in thread "main" java.lang.Exception: OnJ Exception...
at onj.aop.aspectjannotation.OnjWorldImpl.onjHello2(OnjWorldImpl.java:10)
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 onj.aop.aspectjannotation.$Proxy9.onjHello2(Unknown Source)
at onj.aop.aspectjannotation.OnjClient.main(OnjClient.java:12)


오라클자바커뮤니티 오프라인 교육센터, 개발자 전문교육, 개인80%환급 www.oraclejavacommunity.com

평일주간(9:30~18:20) 개강
(5/12)[기업100%환급]Spring ,MyBatis,Hibernate실무과정
(5/12)안드로이드개발자과정
(5/19)C#4.0,ADO.NET,Network 프로그래밍
(5/19)Spring3.X, MyBatis, Hibernate실무과정
(5/19)[기업100%환급]PL/SQL,ORACLE HINT,TUNING
(5/21)[교육전취업확정]Spring,MyBatis,XPlatform실무프로젝트과정
(5/26)SQL초보에서실전전문가까지
(5/27)JAVA,ORACLE 실무개발자과정

평일야간(19:00~21:50) 개강
(5/15)Spring3.X, MyBatis, Hibernate실무과정
(5/16)자바기초에서JSP,Ajax,jQuery,Spring3.2,MyBatis까지
(5/16)C#,ASP.NET마스터
(5/16)SQL초보에서실전전문가까지
(5/16)웹퍼블리싱 마스터
(5/19)안드로이드개발자과정
(5/29)JAVA&WEB프레임워크실무과정

주말(10:00~17:50) 개강
(5/10)Spring3.X, MyBatis, Hibernate실무과정
(5/17)웹퍼블리싱 마스터
(5/17)C#,ASP.NET마스터
(5/17)JAVA&WEB프레임워크실무과정
(5/17)SQL초보에서실전전문가까지
(5/17)안드로이드개발자과정
(5/24)닷넷실무자를위한WPF개발자과정

주말저녁(18:30~22:20) 개강
(5/17)자바&웹,jQUERY,스프링프레임워크
(5/17)SQL기초에서 Schema Object까지


댓글 없음:

댓글 쓰기