JDK动态代理和CGLib代理

来源:互联网 发布:video node 编辑:程序博客网 时间:2024/06/05 07:32

今天国庆节第三天,学习复习spring的实现AOP思想所使用的的原理,主要是JDK动态代理和CGLib动态代理

第一:JDK动态代理

概念:利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理
条件:接口+实现类
缺陷:不能代理实现类,无接口

第二:CGLib(code generize library)

概念:利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理,相当于继承,然后对方法进行增强处理,所以被代理类不能被final修饰
条件:实现类
缺陷:必须依赖于CGLib的类库

实现步骤:

  1. 创建一个实现接口InvocationHandler的类,它必须实现invoke方法
  2. 创建被代理的类以及接口
  3. 通过Proxy的静态方法 newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理
  4. 通过代理调用方法

jdk代理实现

第一步:创建接口和实现类

public interface ItemsService {     //测试jdk代理,cglib不需要接口     void jdkProxy();}public class ItemsServiceImpl implements ItemsService {    public void jdkProxy() {        System.out.println("jdk测试代理方式被执行");    }    public void cglibProxy() {        System.out.println("cglb测试代理方式被执行");    }  }

第二步:创建切面增强类

public class MyAspect {    public void before(){        System.out.println("before");    }    public void after(){        System.out.println("after");    }}

第三步:创建动态代理工具类

public class JDKProxyFactory {    //增强的类    final static MyAspect myAspect=new MyAspect();    //代理创建实例,参数o代表创建的一个空对象    public static Object createInstance(final Object o){    //参数一:类加载器,参数二:接口名,参数三:自定义增强类,采取匿名自定义      Object object= Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(), new InvocationHandler() {            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {               //加入增强的方法                myAspect.before();                //执行原来的方法                Object o1=method.invoke(o,args);                myAspect.after();                return o1;            }        });        //返回代理对象        return object;    }}第四步:测试

public class ProxyTest {

@Testpublic void test1(){    //创建一个空对象    ItemsService itemsService=new ItemsServiceImpl();    //创建代理对象实例    ItemsService itemsService1= (ItemsService) JDKProxyFactory.createInstance(itemsService);    try {        //测试方法        itemsService1.jdkProxy();    } catch (Exception e) {        e.printStackTrace();    }}    

这里写图片描述

cglib代理实现

第一步:创建实现类,不能被final修饰,见jdk代理实现类
第二步:创建增强类,见jdk代理实现
第三步:编写代理类
因为cglib是对指定的类先创建其子类,然后实现其所有方法,所以这里这是对itemsSrviceImpl类进行代理

public class CglibProxyFactory {    //增强的类    final static MyAspect myAspect=new MyAspect();    public static ItemsServiceImpl  createProxy(Object o){        //创建类的子类        final ItemsServiceImpl itemsService=new ItemsServiceImpl();        //创建核心类        Enhancer enhancer=new Enhancer();        //设置父类        enhancer.setSuperclass(itemsService.getClass());        //代理类实现回调方法,类似jdk代理的增强器        enhancer.setCallback(new MethodInterceptor() {            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {                //设置增强方法                myAspect.before();                Object obj=method.invoke(itemsService,args);                //methodProxy.invokeSuper(proxy,args);                //设置增强方法                myAspect.after();                return obj;            }        });        return (ItemsServiceImpl) enhancer.create();    }}

第四步:测试

 @Test    public void test2(){        ItemsServiceImpl itemsService1= CglibProxyFactory.createProxy(new ItemsServiceImpl());        try {            //测试方法            itemsService1.cglibProxy();        } catch (Exception e) {            e.printStackTrace();        }    }

结果为:
这里写图片描述

总结:

jdk代理源码见:http://blog.csdn.net/jiankunking/article/details/52143504

原创粉丝点击