动态代理

动态代理是在运行期间动态地生成代理对象,走出静态代理实现AOP的窘境。

 

基于Proxy的的动态代理:该机制主要有java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口组成。如下:

 

//InvocationHandler是我们实现横切逻辑的地方,它是横切逻辑的载体,作用跟
//AOP中的 Advice一样
public class MyInvocationHandler implements InvocationHandler {
       private Object target;//目标对象

       public MyInvocationHandler 〔Object target〕{
              this.target=target;
       }
       
       public Object invoke〔Object proxy,Method method,object[] 
       args〕throws Throwable{
       if〔method.getName〔〕.equals〔"reuest"〕〕       
          //pre-process
          Object  origrinalObject=method.invoke〔target,args〕;
          //post-process
          return  origrinalObject;
       }  
}

//使用Proxy和MyInvocationHandler创建不同类型目标对象的动态代理

Subject subject=〔Subject〕Proxy.newProxyInstance〔ProxyRunner.class.getClassLoader〔〕,new Class[]{Subject.class},new MyInvocationHandler〔new SubjectImpl〔〕〕〕;

subject.request〔〕;

//如果为其它目标对象创建代理对象,只需改变上面函数的参数即可。

    该代理机制会动态地创建一个$Proxy〔〕类,这个类继承了Proxy并且实现了要代理的目标对象的接口,这也就解释了为什么JDK的动态代理只能代理接口,因为Java是单继承机制。

 

   invoke〔〕方法,第一个参数就是的动态代理对象,第二个参数是目标对象里将要被调用的方法,第三个参数是目标对象里将要被调用的方法的参数。

 

该代理机制缺陷:只能为实现了接口的类进行代理。

 

基于CGLIB〔Code Generation Libray〕的动态代理:建立在ASM基础之上,该代理机制可以为接口或类代理,对目标对象进行继承扩展,为其生成相应的子类,而子类可以通过重写来扩展父类的行为,只要将横切逻辑的实现放到子类中,然后让系统使用扩展后的目标对象的子类即可。主要使用net.sf.cglib.proxy.MethodInterceptor接口和net.sf.cglib.proxy.Enhancer类。如下:

 

// MethodInterceptor是一个回调接口,继承net.sf.cglib.proxy.CallBack回调接口
public MyMethodInterceptor implements MethodInterceptor {
      
       public Ojbect intercept〔Object object, Method method,Object[]  
       args,MethodProxy proxy〕{
        // pre-process
        Object o=proxy.invokeSuper〔object,args〕;
        //post-process
        return o;
      }
}

//运行程序
Enhancer enhancer=new Enhancer〔〕;
//假设SubjectImpl没有 实现任何接口
enhancer.setSuperclass〔SubjectImpl.class〕;
enhancer.setCallBack〔new MyMethodInterceptoer〔〕〕;

SubjectImplProxy proxy=〔SubjectImpl〕enhancer.create〔〕;
proxy.request〔〕;

 intercept〔〕方法中的参数依次为代理对象、被调用方法的Method对象、方法参数、CGLIB提供的方法代理对象,一般来说调用目标方法时,使用最后一个参数,而不直接使用JAVA反射,因为CGLIB使用ASM的字节码操作,代理对iangde执行效率比反射机制高。

 

该机制缺陷:使用CGLIB对类进行扩展的唯一限制就是无法对final方法进行重写。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值