1. 程式人生 > >Spring中的aop(2)

Spring中的aop(2)

用純用純Java的方式實現Spring的切面技術

/*AOP中的一個重要等式:
 *     切面=切點+通知  
 *     advisor=cutpoint+advice
 *     切面: 定義的一個攔截事件(動作)
 *     切點: 要攔截哪些(個)類的哪些(個)方法
 *     通知: 定義在方法的前面、後面、環繞、出異常 還是 正常返回的時候攔
 */

程式碼實現思路:

 1.被代理物件

 2.切點

 技術入口:

  JdkRegexpMethodPointcut cut2 = new JdkRegexpMethodPointcut();

  cut2.setPattern(".*abc.*");

3.通知

4.切面 = 切點 + 通知

5.bean的代理工廠----生產出代理後的bean

  ProxyFactoryBean factory = new ProxyFactoryBean();

  factory.setTarget(p); //設定被代理物件

  factory.addAdvisors(advisor,advisor2);

 6.從代理工廠中取出代理後的bean

  Person p2 = (Person) factory.getObject();

package cn.hncu.aop.v1;

import java.lang.reflect.Method;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.junit.Test;
import org.springframework.aop.Advisor;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.JdkRegexpMethodPointcut;

import cn.hncu.aop.Person;

/*AOP中的一個重要等式: 
 *     切面=切點+通知  
 *     advisor=cutpoint+advice
 *     切面: 定義的一個攔截事件(動作)
 *     切點: 要攔截哪些(個)類的哪些(個)方法
 *     通知: 定義在方法的前面、後面、環繞、出異常 還是 正常返回的時候攔
 */

//用純Java的方式實現Spring的切面技術
public class Demo1 {
	
  @Test
  public void demo(){
	//1 被代理物件
	  Person p = new Person(); 
	
	  //2切點
	  JdkRegexpMethodPointcut cut = new JdkRegexpMethodPointcut();
	  cut.setPattern(".*run.*");
	  
	  //3通知
	  Advice advice = new MethodBeforeAdvice() {
		@Override
		public void before(Method method, Object[] args, Object target)
				throws Throwable {
			System.out.println("在前面攔攔......");
		}
	};
	
	Advice advice2 = new AfterReturningAdvice() {
		@Override
		public void afterReturning(Object returnValue, Method method,
				Object[] args, Object target) throws Throwable {
			System.out.println("後面攔攔,你的返回值是:"+returnValue);
		}
	};

	JdkRegexpMethodPointcut cut2 = new JdkRegexpMethodPointcut();
	cut2.setPattern(".*abc.*");
	 
	cut2.setPattern(".*abc.*");
	  //4 切面 = 切點 + 通知
	  Advisor advisor = new DefaultPointcutAdvisor(cut, advice);
	  Advisor advisor2 = new DefaultPointcutAdvisor(cut2, advice2);
	   
	  //5 bean的代理工廠----生產出代理後的bean
	  //ProxyFactory factory = new ProxyFactory();//低版本Spring用的
	  ProxyFactoryBean factory = new ProxyFactoryBean();
	  factory.setTarget(p); //設定被代理物件
	  factory.addAdvisors(advisor,advisor2);
	  
	  //6 從代理工廠中取出代理後的bean
	  Person p2 = (Person) factory.getObject();
	  
	  p2.run();
	  p2.abc();
  }
  
  
  @Test
  public void demo2(){
	//1 被代理物件
	  Person p = new Person(); 
	  
	  //2切點
	  JdkRegexpMethodPointcut cut = new JdkRegexpMethodPointcut();
	  cut.setPattern(".*run.*");
	  
	  //3通知
	  Advice advice = new AroundAdviceImpl();
	  
	  //4 切面 = 切點 + 通知
	  Advisor advisor = new DefaultPointcutAdvisor(cut, advice);
	  
	  //5 bean的代理工廠----生產出代理後的bean
	  ProxyFactoryBean factory = new ProxyFactoryBean();
	  factory.setTarget(p); //設定被代理物件
	  factory.addAdvisors(advisor);
	  
	  //6 從代理工廠中取出代理後的bean
	  Person p2 = (Person) factory.getObject();
	  
	  p2.run();
	  //p2.abc();
  }
}

通知的實現類 實現MethodInterceptor介面

public class AroundAdviceImpl implements MethodInterceptor{
	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		System.out.println("前面攔截,做動作...");
		Object returnValue = invocation.proceed();//放行
		System.out.println("後面攔截,做動作...");
		return returnValue;
	}
}