动态代理的两种实现方式

来源:互联网 发布:一级域名申请 编辑:程序博客网 时间:2024/05/17 04:10
  最近在阅读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代理之后执行    
原创粉丝点击