Spring AOP的实现机制(一)----- 动态代理

<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>Spring AOP的实现机制

动态代理

  (1)静态代理
  举例说明如下:
  ISubject  该接口是对被访问者或被访问资源的抽象。
  SubjectImpl  被访问者或者被访问资源的具体实现,如果你要访问某位明星,SubjectImpl就是你想访问的明星
  SubjectProxy   被访问者或者被访问资源的代理实现类,该类持有一个ISubject接口的具体实例。在这个场景中,我们要对SubjectImpl进行代理,那么SubjectProxy现在
  持有的就是SubjectImpl的实例。
  
  public class SubjectProxy implements ISubject{
    private ISubject subject;
	public String request(){
	    //add pre-process logic if necessary
		String originalResult=subject.request();
		//add post process logic if necessary
		return "proxy:" +originalResult
	}
	
	public ISubject getSubject(){
	    return subject;
	}
	public void setSubject(ISubject subject){
	    this.subject=subject;
	}
  }
  
  public class SubjectImpl implements ISubject{
    public String request(){
	    //process logic
		return "OK";
	}
  }
  
  这里SubjectImpl和SubjectProxy都实现了相同的接口ISubject ,SubjectProxy内部持有SubjectImpl的引用。
  在将请求转发给被代理对象SubjectImpl之前或者之后,都可以根据情况插入其他处理逻辑。如果SubjectImpl
  是系统中的Joinpoint所在的对象,即目标对象,那么就可以为这个目标对象创建一个代理对象,然后将横切
  逻辑添加到这个代理对象中。当系统使用这个代理对象运行的时候,原有逻辑的实现和横切逻辑就完全融合到
  一个系统中。
  
  然后将代理对象绑定到系统中的实现代码如下:
  ISubject target=new ISubjectImpl();
  ISubject fianlSubject =new SubjectProxy(target);
  fianlSubject.request();
  
  上面属于静态代理,对于多个具有resquest方法的类,我们要为其织入相同的逻辑时又得重新实现一个代理对象,
  所以说静态代理原理上是可行的,但是存在其他问题。
  
  (2)动态代理
  使用动态代理机制,可以为指定的接口在系统运行期间动态生成代理对象。
  动态代理机制的实现主要由一个类和一个接口组成,即java.lang.reflect.Proxy和java.lanf.reflect.InvocationHandler接口
  虽然要为ISubject和IRequestable两种类型提供代理对象,但因为代理对象中药添加的横切逻辑时一样的,所以我们
  只需要实现一个InvocationHandler就可以了。
  简单的实现代码如下:
  public class RequestableInvocationHandler implements InvocationHandler{
    private Object target;
	public  RequestableInvocationHandler(Object target){
	    this.target=target;
	}
	
	public Object invoke(Object proxy,Method method,Object[]args)throws Throwable{
	    if(method.getName().equals("request"))
		{
		    //aspect
		}
		return method.invoke(target,args);
	}
	return null;
  }
  
  然后我们就可以使用Proxy类,根据RequestableInvocationHandler的逻辑,为ISubject和IRequestable两种类型生成相应的代理对象实例
  ISubject subject=(ISubject)Proxy.newProxyInstance(Subject.class.getClassLoader(),new Class[]{ISubject.class},new RequestableInvocationHandler(new SubjectImpl()));
  subject.request();
  
  IRequestable requestable=(IRequestable)Proxy.newProxyInstance(IRequestable.class.getClassLoader(),new Class[]{IRequestable.class},new RequestableInvocationHandler(new RequestableImpl()));
  requestable.request();
  
  InvocationHandler就是我们实现横切逻辑的地方,它是横切逻辑的载体,作用和Advice一样。所以在使用动态代理机制实现AOP的过程
  中,我们可以在InvocationHandler的基础上细化程序结构,并根据Advice的类型,分化出对应不同Advice类型的程序结构。
  
  动态代理虽好,但是不能满足所有需求。因为动态代理机制只能对实现了相应Interface的类使用,如果某个类没有实现任何的Interface
  就无法使用动态代理为其生成相应的动态代理对象
  
  默认情况下,如果Spring AOP发现目标对象实现了相应Interface,则采用动态代理机制为其生成代理对象实例。而如果目标对象没有实现任何Interface,Spring AOP 会尝试使用CGLIB
  (Code Genaration Library)的开源的动态字节码生成类库,为目标对象动态生成代理对象
  
  定义目标类如下:
  pubic class Requestable{
    public void request(){
	    System.out.println("rq in Requestable without implement any interface");
	}
  }
  
  
  要对Requestable类进行扩展,首先需要实现一个net.sf.cglib.proxy.Callback。不过更多的时候我们直接使用net.sf.cglib.proxy.MethodInterceptor接口
  
  public class RequestCtrlCallback implements MethodInterceptor{
    public Object intercept(Object object,Method method,Object[]args,MethodProxy proxy)throws Throwable{
	    if(method.getName.equals("request")){
		    //process logic;
			return proxy.invokeSuper(object,args);
		}
		
	}
  }
  
  这样,RequestableCallback就实现了对request()方法请求进行访问控制的逻辑。现在通过CGLIB的Enhancer为目标对象动态生成一个子类,
  并将RequestableCallback中的横切逻辑附加到该子类中.
  Enhancer enchaner=new Enhancer();
  enchaner.setSuperclass(Requestable.class);
  enchaner.setCallback(new RequestableCallback());
  Requestable proxy =(Requestable)enchaner.create();
  proxy.request();
  
  
  
  </strong></span>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值