2013년 7월 27일 토요일

[오라클자바개발자실무교육,오엔제이프로그래밍실무교육센터,Spring Framework3.2]Spring AOP(Spring 선언적 AOP @AspectJ 애노테이션)

Spring AOP(Spring 선언적 AOP  @AspectJ 애노테이션)



오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷  실무전문 강의)



  
Spring AOP와 JDK 1.5 이상인 경우 애노테이션을 이용하여 어드바이스를 선언 할 수 있다.
Spring은 @AspectJ에서 제공하는 애노테이션 및 구문을 활용하는 @AspectJ 방식의 애노테이션을 지원한다.
타겟 메소드에 어드바이스를 적용할 때는 AspectJ의 위빙 메커니즘이 아니라 자체 프록시 메커니즘을 이용한다.
[MyDependency.java]
package onj.edu.aop11;
import org.springframework.stereotype.Component;
//충고를 받을 빈, MyBean의 setter로 주입된다.
@Component("myDependency")
public class MyDependency {
 public void hello(int intValue) {
  System.out.println("hello... OnJ" + intValue);
 }
 public void goodbye() {
  System.out.println("goodbye... OnJ");
 }
}
[MyBean.java]
package onj.edu.aop11;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
//의존객체(MyDependency)를 주입받고 run() 메인에서 호출당함
@Component("myBean")
public class MyBean {
 private MyDependency dependency;

 public void run() {
  dependency.hello(5919);
  dependency.hello(4790);
  dependency.goodbye();
 }
 //Spring에서 의존성을 자동 주입
 @Autowired
 public void setDependency(MyDependency dependency) {
  this.dependency = dependency;
 }
}

[MyAdvice.java]

package onj.edu.aop11;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
//타겟이 되는 MyDendency의 hello()에 적용될 충고
@Component //XML설정에서 <component:component-scan> 태그로 컴포넌트를 스캔가능하도록
@Aspect    //애스팩트 클래스임을 표시
public class MyAdvice {

 //
 @Pointcut("execution(* onj.edu.aop11..hello*(int)) && args(intValue)")
 public void helloExec(int intValue) {}

 @Pointcut("bean(myDependency*)")
 public void inMyDependency() {}

 //@AspectJ는 &&, aop 네임스페이스는 and 임. 주의
 @Before("helloExec(intValue) && inMyDependency()")
 public void simpleBeforeAdvice(JoinPoint joinPoint, int intValue) {
  //인자가 5000보다 커야 충고 적용
  if (intValue > 5000) {
     System.out.println("충고실행 ::: " + joinPoint.getSignature().getDeclaringTypeName() + "," + joinPoint.getSignature().getName());
  }
 }
 //Around Advice, 두 포인트컷에 이 어드바이스 적용할 때 모두 충족해야 한다는 뜻
 @Around("helloExec(intValue) && inMyDependency()")
 public Object simpleAroundAdvice(ProceedingJoinPoint joinPoint, int intValue) throws Throwable {
  System.out.println("before advice ::: " + joinPoint.getSignature().getDeclaringTypeName() + "," + joinPoint.getSignature().getName());
  Object retVal = joinPoint.proceed();
  System.out.println("after advice ::: " + joinPoint.getSignature().getDeclaringTypeName() + "," + joinPoint.getSignature().getName());

  return retVal;
 }
}
[aop-context9.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"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:util="http://www.springframework.org/schema/util"
 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
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  http://www.springframework.org/schema/util   http://www.springframework.org/schema/util/spring-util-3.2.xsd">

  <aop:aspectj-autoproxy/>
  <context:component-scan base-package="onj.edu.aop11"/>
</beans>  
[AopNamesapceExam2.java]
package onj.edu.aop11;
import org.springframework.context.support.GenericXmlApplicationContext;
public class AopNamespaceExam2 {
 public static void main(String[] args) {
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
  ctx.load("classpath:app-context11.xml");
  ctx.refresh();

  MyBean bean = (MyBean)ctx.getBean("myBean");

  System.out.println("---- bean ---");
  bean.run();

  ctx.close();
 }
}
}
}
[결과]
before advice ::: onj.edu.aop11.MyDependency,hello
충고실행 ::: onj.edu.aop11.MyDependency,hello
hello... OnJ5919
after advice ::: onj.edu.aop11.MyDependency,hello
before advice ::: onj.edu.aop11.MyDependency,hello
hello... OnJ4790
after advice ::: onj.edu.aop11.MyDependency,hello
goodbye... OnJ

댓글 없음:

댓글 쓰기