动态代理的两种实现方式

  最近在阅读Spring源码,对于Spring AOP动态代理的两种实现方式--JDK动态代理以及Cglib动态代理的实现又重新回顾了一下。特此记录。

一、JDK动态代理

         这是通过java反射机制来实现的,它所对应的类必须有接口。
         Jdk动态代理主要有两个重要的地方:
               InvocationHandler:每一个动态代理类都需要折现这样一个接口,每一个动态代理类都关联到这样一个 实例。当我们调用方法时候。转而由InvocationHandler.invoke执行相应的操作
               Proxy:通过它的方法创建动态代理对象,常用方法就是newProxyInstance,
 它三个参数的含义:ClassLoader loader:由哪个ClassLoader对象来对生成的代理对象进行加载
               Class<?>[] interfaces:需要被代理的类实现的接口
               InvocationHandler h   具体的InvocationHandler实例,通过它执行方法

具体代码:

   先写一个接口:
  public interface UserService {
    public void show();
}
public class UserServiceImpl implements  UserService {//接口实现类
    @Override
    public void show() {
        System.out.println("I am a User");
    }
}
public class JdkProxy implements InvocationHandler {//继承InvocationHandler并获得实例

    private Object object;
    public JdkProxy(){
    }
    public Object getProxy(Object object){
        this.object=object;
        return Proxy.newProxyInstance(getClass().getClassLoader(),object.getClass().getInterfaces(),this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("代理之前执行");
        Object result=method.invoke(object,args);
        System.out.println("代理之后执行");
        return  result;
    }
}    

输出:

代理之前执行
I am a User
代理之后执行

二、通过Cglib技术实现动态代理

     Cglib技术底层通过字节码方式实现的动态代理。它与JDk动态代理不同的地方是它不需要一个类实现接口。它是通过动态生成被代理类的子类,当调用被代理类的方法时候,会被子类的方法拦截器拦截然后增强。
     MethodInterceptor:方法拦截器,在调用目标方法的时候会调用它的实现类进行拦截。它最重要方法为intercept,进行拦截并执行。
    intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)
     o表示被增强后的对象。method表示原始对象的方法,object表示执行方法所需参数,methodProxy表示被增强的方法。
      其中,methodProxy需要注意,它有两个方法,invokeSuper(),表示执行超类的对应方法,invoke表示执行当前类的方法,这两者使用不当会造成无限递归调用。

     Enhancer:是增强器,它对你想处理的类进行扩展
              enhancer.setSuperclass:设置需要增强的类(相当于父类)
              enhancer.setCallback:设置回调的拦截器 

具体代码:   
public class CglibProxy implements MethodInterceptor {

    private Enhancer enhancer=new Enhancer();
    public Object  getProxy(Object object){
        enhancer.setSuperclass(object.getClass());
        enhancer.setCallback(this);
        return  enhancer.create();
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("代理之前");
        Object result=methodProxy.invokeSuper(o,objects);
        System.out.println("代理之后");
        return  result;
    }
    @Test
    public  void test(){
        CglibProxy cglibProxy=new CglibProxy();
        User user= (User) cglibProxy.getProxy(new User());
        user.show();
    }
}
输出:
代理之前执行
I am a User
代理之后执行    
posted @ 2017-11-27 17:35  十禾。  阅读(342)  评论(0编辑  收藏  举报