Spring AOP 동적 에이전트 CGLib Aspectj

34302 단어 spring aop
0. AOP 실현 원리
측면 프로 그래 밍 (Aspect) Oriented Programming, 약칭 AOP) 는 일종 의 성명 식 프로 그래 밍 (Declarative Programming)。AOP 의 실현 원 리 는 Proxy / Decorator 디자인 모델 의 일반화 로 볼 수 있 는데 다음 과 같이 Proxy 모델 의 간단 한 예 이다.
Proxy { 
    innerObject; //       
    f1() { 
        //         
        innerObject.f1(); //             
        //          
    } 
} 

1. 에이 전 트 를 사용 하여 AOP 실현
서비스 클래스 인터페이스 IService. java 설명:
package com.chenzehe.aop;
public interface IService {
	int save();
}
 
구현 클래스:
package com.chenzehe.aop;
public class Service implements IService {
	final Logger	log	= LoggerFactory.getLogger(Service.class);
	
	@Override
	public int save() {
		log.info("*****save*****");
		return 0;
	}	
}

프 록 시 클래스 ServiceProxy 도 IService 인 터 페 이 스 를 실현 하고 내부 호출 Service 의 실현 방법 을 실현 하 며 앞 과 배경 에 자신의 절단면 방법 을 추가 합 니 다.
package com.chenzehe.aop;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ServiceProxy implements IService {
	final Logger	log	= LoggerFactory.getLogger(ServiceProxy.class);
	private IService	service;	
	public ServiceProxy(IService service) {
		this.service = service;
	}
	
	@Override
	public int save() {
		int result;
		log.debug("*****Before*****");
		result = service.save();
		log.debug("*****After*****");
		return result;
	}	
}

유닛 테스트 클래스 프 록 시 테스트 사용 ServiceProxy 추가:
import org.junit.Test;
public class ProxyTest {
	@Test
	public void testSave() {
		IService service = new ServiceProxy(new Service());
		service.save();
	}
}
    :
ServiceProxy - *****Before*****
       *****save*****
ServiceProxy - *****After*****

 2. 동적 에이전트 로 AOP 구현
위의 코드 는 가장 간단 한 AOP 기능 을 실현 했다. 그러나 프로젝트 에 Service 와 같은 종류 가 많다 면 ServiceProxy 와 같은 프 록 시 류 를 많이 써 서 실현 해 야 하기 때문에 동적 코드 방법 으로 실현 해 야 한다. 즉, Invocation Handler 의 인 터 페 이 스 를 실현 하 는 것 이다. 이런 종 류 는 JVM 에서 특정한 방법 을 호출 할 때 동태 적 으로 어떤 방법 을 위해 무엇 을 할 수 있 는 지,다음 코드, IService 인터페이스 와 구현 클래스 Service 가 변 하지 않 습 니 다. 동적 프 록 시 구현 클래스 DynamicProxy 를 추가 합 니 다.
 
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DynamicProxy implements InvocationHandler {
	final Logger	log = LoggerFactory.getLogger(ServiceProxy.class);
	/**
	 *       (                     )
	 */
	private Object	delegate;
	
	/**
	 *                (    )
	 */
	public Object bind(Object delegate) {
		this.delegate = delegate;
		return Proxy.newProxyInstance(this.delegate.getClass().getClassLoader(), this.delegate.getClass().getInterfaces(), this);
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object result;
		log.debug("*****Before*****");
		result = method.invoke(this.delegate, args);
		log.debug("*****After*****");
		return result;
	}
	
}

 유닛 테스트 코드 는 다음 과 같 습 니 다.
 
package com.chenzehe.aop;

import org.junit.Test;

public class DynamicProxyTest {
	@Test
	public void testSave() {
		IService service = (IService) new DynamicProxy().bind(new Service());
		service.save();
	}
}

  :
ServiceProxy - *****Before*****
       *****save*****
ServiceProxy - *****After*****

 
 3. 알림 디 결합
위의 코드 는 절단면 통 지 를 실 현 했 지만 알림 방법 은 모두 대리 방법 에서 이 루어 졌 습 니 다. 이렇게 결합 도가 너무 높 아서 우 리 는 하나의 인 터 페 이 스 를 추상 화 할 수 있 습 니 다. 이 인터페이스 에는 두 가지 방법 만 있 습 니 다. 하 나 는 대리 대상 이 방법 을 실행 하기 전에 실행 하 는 방법 입 니 다. 우 리 는 before 라 고 이름 을 지 었 습 니 다.두 번 째 방법 은 대리 대상 이 방법 을 실행 한 후에 실행 하 는 방법 입 니 다. 우 리 는 after 라 고 이름 을 지 었 습 니 다. 인 터 페 이 스 는 다음 과 같이 정의 합 니 다.
package com.chenzehe.aop;

import java.lang.reflect.Method;

public interface IOperation {
	/**
	 *          
	 * 
	 * @param method
	 */
	void before(Method method);
	
	/**
	 *          
	 * 
	 * @param method
	 */
	void after(Method method);
}

 우 리 는 위의 인 터 페 이 스 를 실현 하 는 종 류 를 쓰 러 간다. 우 리 는 그의 진정한 조작 자가 될 것 이다. 예 를 들 어 다음은 로그 조작 자의 종류 이다.
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LoggerOperation implements IOperation {
	final Logger	log = LoggerFactory.getLogger(LoggerOperation.class);
	
	@Override
	public void before(Method method) {
		log.info("Before:" + method.getName());
	}
	
	@Override
	public void after(Method method) {
		log.info("After:" + method.getName());
	}
	
}

 동적 에이전트 구현 클래스:
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class OperationDynamicProxy implements InvocationHandler {
	/**
	 *       (                     )
	 */
	private Object	delegate;
	/**
	 *       
	 */
	private Object	operation;
	
	public OperationDynamicProxy() {
	}
	
	/**
	 *                (    )
	 */
	public Object bind(Object delegate, Object operation) {
		this.delegate = delegate;
		this.operation = operation;
		
		return Proxy.newProxyInstance(this.delegate.getClass().getClassLoader(), this.delegate.getClass().getInterfaces(), this);
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object result;
		//           
		Class clazz = this.operation.getClass();
		//         before  
		Method start = clazz.getDeclaredMethod("before", new Class[] { Method.class });
		//     before  
		start.invoke(this.operation, new Object[] { method });
		//             
		result = method.invoke(this.delegate, args);
		//         end  
		Method end = clazz.getDeclaredMethod("after", new Class[] { Method.class });
		//     end  
		end.invoke(this.operation, new Object[] { method });
		return result;
	}
	
}

 테스트 클래스:
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

import org.junit.Test;

public class OperationDynamicProxyTest {
	@Test
	public void testSave() {
		IService service = (IService) new OperationDynamicProxy().bind(new Service(), new LoggerOperation());
		service.save();
	}
}

  :
LoggerOperation - Before:save
       *****save*****
LoggerOperation - After:save

 
4 、 CGLib 로 구현
위 에서 AOP 에서 피 에이전트 대상 은 모두 인 터 페 이 스 를 제공 합 니 다. 가끔 은 우리 의 수요 에서 피 에이전트 클래스 가 인 터 페 이 스 를 제공 하지 않 을 때 CGLib 를 사용 하여 이 루어 집 니 다. CGLib 실현 원 리 는 피 에이전트 클래스 를 계승 하고 피 에이전트 클래스 를 다시 쓰 는 방법 입 니 다. 그리고 재 작성 방법 에 자신의 절단면 방법 을 추가 하 는 것 입 니 다.
제공 되 지 않 은 클래스:
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

public class ServiceNotInterface {
	final Logger	log	= LoggerFactory.getLogger(ServiceNotInterface.class);
	
	public int save() {
		log.info("*****save*****");
		return 0;
	}	
}

 CGLib 구현 클래스:
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CGLibProxy implements MethodInterceptor {
	/**
	 *       
	 */
	private Object	delegate;
	/**
	 *       
	 */
	private Object	operation;
	
	/**
	 *               
	 */
	public Object bind(Object delegate, Object operation) {
		this.delegate = delegate;
		this.operation = operation;
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(this.delegate.getClass());
		//     
		enhancer.setCallback(this);
		//       
		return enhancer.create();
		
	}
	
	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		Object result;
		//           
		Class clazz = this.operation.getClass();
		//         before  
		Method start = clazz.getDeclaredMethod("before", new Class[] { Method.class });
		//     before  
		start.invoke(this.operation, new Object[] { method });
		//             
		result = methodProxy.invokeSuper(proxy, args);
		//         end  
		Method end = clazz.getDeclaredMethod("after", new Class[] { Method.class });
		//     end  
		end.invoke(this.operation, new Object[] { method });
		return result;
	}
	
}

 테스트 클래스:
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

import java.lang.reflect.Method;

import org.junit.Test;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CGLibProxyTest {
	@Test
	public void testSave() {
		ServiceNotInterface service = (ServiceNotInterface) new CGLibProxy().bind(new ServiceNotInterface(), new LoggerOperation());
		service.save();
	}
}

  :
LoggerOperation - Before:save
       *****save*****
LoggerOperation - After:save

 
 5. Spring AOP 개념
       절단면 (aspect): 업무 방법 을 삽입 하 는 클래스 입 니 다.연결 점 (joinpoint): 절단면 류 와 업무 류 의 연결 점 입 니 다. 사실은 업무 방법의 기본 속성 을 밀봉 하여 알림 의 매개 변수 로 분석 합 니 다.알림 (advice): 절단면 류 에서 업무 방법 에 대해 추가 로 처리 하 는 방법 을 설명 합 니 다.접점 (pointcut): 업무 클래스 에서 지정 한 방법 으로 절단면 으로 들 어 가 는 점 입 니 다.사실은 어떤 방법 을 절단면 으로 자 르 는 곳 으로 지정 하 는 것 이다.대상 (target object): 대리 대상.AOP 에이전트 (aop proxy): 에이전트 대상.사전 알림 (before advice): 접점 에 들 어가 기 전에 실행 합 니 다.후방 알림 (after returning advice): 삽입점 에서 실행 이 끝 난 후 알림 을 실행 합 니 다.서 라운드 알림 (around advice): 접근 점 을 포위 하고 호출 방법 전후 로 사용자 정의 행 위 를 완성 합 니 다.이상 알림 (after throwing advice): 접점 에서 이상 을 던 진 후 알림 을 실행 합 니 다.
       Spring 은 AOP 를 실현 하 는 세 가지 방식, Spring 인터페이스 방식, schema 설정 방식 과 주해 방식 의 세 가지 실현 방식 을 제공 했다.
6. 인터페이스 방식
Spring AOP 인 터 페 이 스 를 이용 하여 AOP 를 실현 하 는 것 은 주로 사용자 정의 알림 을 지정 하여 spring AOP 메커니즘 을 식별 할 수 있 도록 하기 위 한 것 이다.주요 인터페이스: 사전 알림 MethodBeforeAdvice, 사후 알림: AfterReturning Advice, 서 라운드 알림: MethodInterceptor, 이상 알림: ThrowsAdvice.다음 코드:
위의 인터페이스 IService 와 구현 클래스 Service 를 사용 합 니 다.
사전 알림:
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.MethodBeforeAdvice;

/**
 *     
 */

public class BaseBeforeAdvice implements MethodBeforeAdvice {
	
	final Logger	log	= LoggerFactory.getLogger(BaseBeforeAdvice.class);
	
	/**
	 * method :       <br>
	 * args :        <br>
	 * target :    
	 */
	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		log.info("===========  beforeAdvice()============ 
"); log.info(" " + target + " "); log.info(method + " "); log.info("
"); } }

 나중에 알림:
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.AfterReturningAdvice;

/**
 *     
 */
public class BaseAfterReturnAdvice implements AfterReturningAdvice {
	
	final Logger	log	= LoggerFactory.getLogger(BaseAfterReturnAdvice.class);
	
	/**
	 * returnValue :            ,      <br>
	 * method :      <br>
	 * args :           <br>
	 * target :    
	 */
	@Override
	public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
		log.info("==========  afterReturning()=========== 
"); } }

 서 라운드 알림:
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *     
 */

public class BaseAroundAdvice implements MethodInterceptor {
	final Logger	log	= LoggerFactory.getLogger(BaseAroundAdvice.class);
	
	/**
	 * invocation :   
	 */
	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		log.info("===========  around    !=========== 
"); // log.info(" : !
"); // Object[] args = invocation.getArguments(); // Method method = invocation.getMethod(); // Object target = invocation.getThis(); // : proceed() , Object returnValue = invocation.proceed(); log.info("=========== around !===========
"); log.info(" :" + args + ";" + method + ";" + target + ";" + returnValue + "
"); log.info(" : !
"); return returnValue; } }

 이상 알림:
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.ThrowsAdvice;

/**
 *     ,          。       
 */
public class BaseAfterThrowsAdvice implements ThrowsAdvice {
	final Logger	log	= LoggerFactory.getLogger(BaseAfterThrowsAdvice.class);
	
	/**
	 *     ,          
	 * 
	 * @param method
	 *              :     
	 * @param args
	 *              :        
	 * @param target
	 *              :    
	 * @param throwable
	 *               :     ,          ,        。
	 */
	public void afterThrowing(Method method, Object[] args, Object target, Throwable throwable) {
		log.info("   ");
	}
}

 지정 한 접점 정의:
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

import java.lang.reflect.Method;

import org.springframework.aop.support.NameMatchMethodPointcut;

/**
 *       ,        。             <br>
 *   NameMatchMethodPointcut ,       
 */
public class Pointcut extends NameMatchMethodPointcut {
	
	private static final long	serialVersionUID	= 5891054717975242200L;
	
	@SuppressWarnings("rawtypes")
	@Override
	public boolean matches(Method method, Class targetClass) {
		//         
		this.setMappedName("delete");
		//         
		String[] methods = { "delete", "save" };
		
		//     “ * ”       
		// this.setMappedName("get*");
		
		this.setMappedNames(methods);
		
		return super.matches(method, targetClass);
	}
}

 설정:
<?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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	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.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"
	default-autowire="byName">

	<!-- ==============================  spring   aop  ================================ -->
	<!--         -->
	<bean id="service" class="com.chenzehe.aop.Service" />

	<!--       -->
	<bean id="baseBefore" class="com.chenzehe.aop.BaseBeforeAdvice" />
	<bean id="baseAfterReturn" class="com.chenzehe.aop.BaseAfterReturnAdvice" />
	<bean id="baseAfterThrows" class="com.chenzehe.aop.BaseAfterThrowsAdvice" />
	<bean id="baseAround" class="com.chenzehe.aop.BaseAroundAdvice" />

	<!--         -->
	<bean id="pointcut" class="com.chenzehe.aop.Pointcut" />

	<!--     ,     -->
	<bean id="matchBeforeAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
		<property name="pointcut">
			<ref bean="pointcut" />
		</property>
		<property name="advice">
			<ref bean="baseBefore" />
		</property>
	</bean>

	<!--   ProxyFactoryBean        -->
	<bean id="businessProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<!--            ,            -->
		<property name="proxyInterfaces">
			<value>com.chenzehe.aop.IService</value>
		</property>

		<!--        -->
		<property name="target">
			<ref local="service" />
		</property>
		<!--             -->
		<property name="interceptorNames">
			<list>
				<value>matchBeforeAdvisor</value>
				<value>baseAfterReturn</value>
				<value>baseAround</value>
			</list>
		</property>
	</bean>
</beans>

 테스트 클래스:
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

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

public class SpringAopInterfaceTest {
	
	@Test
	public void testSpringAopInterface() {
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");
		IService service = (IService) context.getBean("businessProxy");
		service.save();
	}
}

 출력:
       BaseBeforeAdvice - ===========  beforeAdvice()============ 

       BaseBeforeAdvice -    com.chenzehe.aop.Service@1e136a8    
       BaseBeforeAdvice - public abstract int com.chenzehe.aop.IService.save()  
       BaseBeforeAdvice -           

       BaseAroundAdvice - ===========  around    !=========== 

       BaseAroundAdvice -       :   !

       Service - *****save*****
       BaseAroundAdvice - ===========    around    !=========== 

       BaseAroundAdvice -   :[Ljava.lang.Object;@ee558f;public abstract int com.chenzehe.aop.IService.save();com.chenzehe.aop.Service@1e136a8;0

       BaseAroundAdvice -       :    !

       BaseAfterReturnAdvice - ==========  afterReturning()=========== 

       선행 방법 은 삽입점 방법 전에 실행 되 고, 선행 방법 은 삽입점 방법 이 실 행 된 후에 실행 되 며, 서 라운드 방법 은 삽입점 방법 이 실 행 될 때 까지 동료의 방법 이 끝나 도 대응 하 는 부분 을 실행한다.주로 proceed () 방법 을 호출 하여 접점 방법 을 실행 합 니 다.businessProxy 라 는 bean 을 설정 할 때 Proxy Factory Bean 클래스 에서 'proxy Interfaces 인자' 를 지정 합 니 다.여기 서 그 를 IService 인터페이스 로 설정 했다.프로젝트 개발 과정 에서 업무 류 에 대응 하 는 인터페이스 가 있어 IOC 디 결합 을 편리 하 게 이용 하기 때문이다.그러나 스프링 AOP 는 인터페이스 가 없 는 에이 전 트 를 지원 할 수 있다.이것 이 바로 cglib. jar 의 가방 을 가 져 와 야 하 는 이유 입 니 다.목표 접근 대상 에 실현 인터페이스 가 있 으 면 spring 은 기본적으로 jdk 동적 대 리 를 통 해 대리 류 를 실현 합 니 다.인터페이스 가 없 으 면 cglib 를 통 해 프 록 시 클래스 를 구현 합 니 다.
 
 7 、 AOP 설정 을 위해 aspectj 사용
위 에 인터페이스 가 구현 되 지 않 은 비 즈 니스 클래스 ServiceNotInterface 를 사용 합 니 다.
절단면 클래스 AspectAdvice 를 정의 합 니 다. 모든 알림 이 포함 되 어 있 습 니 다.
package com.chenzehe.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *       
 * 
 */
public class AspectAdvice {
	final Logger	log	= LoggerFactory.getLogger(AspectAdvice.class);
	
	/**
	 *     
	 * 
	 * @param jp
	 *               
	 */
	public void doBefore(JoinPoint jp) {
		log.info("===========  before advice============ 
"); log.info("
"); } /** * * * @param jp * * @param result * */ public void doAfter(JoinPoint jp, String result) { log.info("========== after advice===========
"); } /** * * * @param pjp * */ public void doAround(ProceedingJoinPoint pjp) throws Throwable { log.info("=========== around !===========
"); // log.info(" : !
"); // Object[] args = pjp.getArgs(); // String method = pjp.getSignature().getName(); // Object target = pjp.getTarget(); // : proceed() , Object result = pjp.proceed(); log.info(" :" + args + ";" + method + ";" + target + ";" + result + "
"); log.info(" : !
"); } /** * * * @param jp * @param e */ public void doThrow(JoinPoint jp, Throwable e) { log.info(" "); } }

 프로필:
<?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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	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.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"
	default-autowire="byName">

	<!-- ==============================  spring   aspectj   AOP================================ -->

	<!--         -->
	<bean id="aspectBusiness" class="com.chenzehe.aop.ServiceNotInterface" />

	<!--       -->
	<bean id="aspectAdvice" class="com.chenzehe.aop.AspectAdvice" />

	<aop:config>
		<aop:aspect id="businessAspect" ref="aspectAdvice">
			<!--           -->
			<aop:pointcut id="point_cut" expression="execution(* com.chenzehe.aop.ServiceNotInterface.*(..))" />

			<!--      -->
			<aop:before method="doBefore" pointcut-ref="point_cut" />
			<!--      returning       -->
			<aop:after-returning method="doAfter"
				pointcut-ref="point_cut" returning="result" />
			<aop:around method="doAround" pointcut-ref="point_cut" />
			<aop:after-throwing method="doThrow" pointcut-ref="point_cut"
				throwing="e" />
		</aop:aspect>
	</aop:config>
</beans>

 테스트 클래스:
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

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

public class SpringAopAspectjTest {
	@Test
	public void testSpringAopAspectj() {
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-aspectj-aop.xml");
		ServiceNotInterface service = (ServiceNotInterface) context.getBean("aspectBusiness");
		service.save();
	}
}

 출력:
       AspectAdvice - ===========  before advice============ 

       AspectAdvice -           

       DefaultListableBeanFactory - Returning cached instance of singleton bean 'aspectAdvice'
       AspectAdvice - ===========  around    !=========== 

       AspectAdvice -       :   !

       ServiceNotInterface - *****save*****
       AspectAdvice -   :[Ljava.lang.Object;@edf389;save;com.chenzehe.aop.ServiceNotInterface@59fb21;0

       AspectAdvice -       :    !

 
 8. aspectj 주 해 를 사용 하여 AOP 를 설정 합 니 다.
주석 기반 service 클래스:
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @description
 * 
 * @author chenzehe
 * @email [email protected]
 */
@Component
public class ServiceAnonotation {
	final Logger	log	= LoggerFactory.getLogger(ServiceAnonotation.class);
	
	public int save() {
		log.info("*****save*****");
		return 0;
	}
	
}

 주석 기반 절단면:
package com.chenzehe.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
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;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 *       
 * 
 */
@Component
@Aspect
public class AspectAdviceAnonotation {
	final Logger	log	= LoggerFactory.getLogger(AspectAdviceAnonotation.class);
	
	/**
	 *           ,               。
	 */
	@Pointcut("execution(* com.chenzehe.aop.*.*(..))")
	public void anyMethod() {
	}
	
	/**
	 *     
	 * 
	 * @param jp
	 */
	@Before(value = "execution(* com.chenzehe.aop.*.*(..))")
	public void doBefore(JoinPoint jp) {
		log.info("===========  before advice============ 
"); log.info("
"); } /** * * * @param jp * * @param result * */ @AfterReturning(value = "anyMethod()", returning = "result") public void doAfter(JoinPoint jp, String result) { log.info("========== after advice===========
"); } /** * * * @param pjp * */ @Around(value = "execution(* com.chenzehe.aop.*.*(..))") public void doAround(ProceedingJoinPoint pjp) throws Throwable { log.info("=========== around !===========
"); // log.info(" : !
"); // Object[] args = pjp.getArgs(); // String method = pjp.getSignature().getName(); // Object target = pjp.getTarget(); // : proceed() , Object result = pjp.proceed(); log.info(" :" + args + ";" + method + ";" + target + ";" + result + "
"); log.info(" : !
"); } /** * * * @param jp * @param e */ @AfterThrowing(value = "execution(* com.chenzehe.aop.*.*(..))", throwing = "e") public void doThrow(JoinPoint jp, Throwable e) { log.info(" "); } }

 프로필:
<?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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	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.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"
	default-autowire="byName">

	<context:component-scan base-package="com.chenzehe.aop" />
	<!--   aop    -->
	<aop:aspectj-autoproxy />

</beans>

 테스트 클래스:
/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package com.chenzehe.aop;

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

/**
 * @description
 * 
 * @author chenzehe
 * @email [email protected]
 */

public class SpringAopAspectjAnonotationTest {
	@Test
	public void testSpringAopAspectjAnonotation() {
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-aspectj-anonotation-aop.xml");
		ServiceAnonotation service = (ServiceAnonotation) context.getBean("serviceAnonotation");
		service.save();
	}
}

 출력:
       AspectAdviceAnonotation - ===========  before advice============ 

       AspectAdviceAnonotation -           

       AspectAdviceAnonotation - ===========  around    !=========== 

       AspectAdviceAnonotation -       :   !

       ServiceAnonotation - *****save*****
       AspectAdviceAnonotation -   :[Ljava.lang.Object;@7ecd78;save;com.chenzehe.aop.ServiceAnonotation@16be68f;0

       AspectAdviceAnonotation -       :    !

 
 

좋은 웹페이지 즐겨찾기