AOP之JDK动态代理和CGLib动态代理

Posted ruanjiancainiao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AOP之JDK动态代理和CGLib动态代理相关的知识,希望对你有一定的参考价值。

一、JDK动态代理

 JDK内置的Proxy动态代理可以在运行时动态生成字节码,而没必要针对每个类编写代理类。中间主要使用到了一个接口InvocationHandler与Proxy.newProxyInstance静态方法,参数说明如下:

 使用内置的Proxy实现动态代理有一个问题:被代理的类必须实现接口,未实现接口则没办法完成动态代理。

1.编写接口类

public interface IUserDao {
    public String add();
    public String edit();
}

2.编写实现类

public class UserDaoImpl implements IUserDao {
    public String add() {
        System.out.println("add");
        return "add";
    }

    public String edit() {
        System.out.println("edit");
        return "edit";
    }
}

3.编写测试类

    //JDK动态代理
    @Test
    public void  DTTest(){
       final IUserDao dao = new UserDaoImpl();
        IUserDao proxy =(IUserDao)Proxy.newProxyInstance(dao.getClass().getClassLoader(), dao.getClass().getInterfaces(), new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("事物已经开启!");
                method.invoke(dao,args);
                return null;
            }
        });
        //代理对象add edit
        proxy.add();
        proxy.edit();
    } 

4.测试结果

二、CGLIB动态代理

CGLIB(Code Generation Library)是一个开源项目,是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口,通俗说cglib可以在运行时动态生成字节码。不需要有接口。

原理是:cglib继承被代理的类,重写方法,织入通知,动态生成字节码并运行 

cglib封装了asm,可以在运行期动态生成新的class。

1.编写业务类

public class UserService {
    //核心业务方法
    public void  deleter(){
        System.out.println("delete ok");
    }
}

2.编写测试类

    //CGLIB动态代理
    @Test
    public void testCGlib() {
        //对方法进行增强,不破坏原有方法的业务
        //1.创建一个目标对象
        final UserService service = new UserService();
        //2.Enhancer对象
        Enhancer enhancer = new Enhancer();
        //3.在内存中构建业务类的子类    //设置父类
        enhancer.setSuperclass(service.getClass());

 /*  1、第一种方法
     enhancer.setCallback(new MethodInterceptor() {
            *//*
            * 第一个参数:Object为由CGLib动态生成的代理类实例
            * 第二个参数:Method为上文中实体类所调用的被代理的方法引用
            * 第三个参数:Object[]为参数值列表
            * 第四个参数:MethodProxy为生成的代理类对方法的代理引用
            * *//*
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("事物已经开启");
                methodProxy.invoke(service,objects);
                return null;
            }
        });*/


        //4.调度setCallback     第二种方法
        enhancer.setCallback(new org.springframework.cglib.proxy.InvocationHandler() {
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                System.out.println("事物已经开启");
                method.invoke(service,objects);
                return null;
            }
        });
        //enhancer对象create方法创建出一个代理
        UserService proxy = (UserService)enhancer.create();
        //执行代理对象的deleter方法
        proxy.deleter();
    }

3.测试结果

 

  

  

 

  

 

以上是关于AOP之JDK动态代理和CGLib动态代理的主要内容,如果未能解决你的问题,请参考以下文章

AOP动态代理之CGLIB代理

Spring读源码系列之AOP--06---AopProxy===>spring使用jdk和cglib生成代理对象的终极奥义

JDK动态代理和cglib动态代理(AOP的底层实现原理)

Spring AOP详解 JDK动态代理CGLib动态代理

转载Spring AOP详解 JDK动态代理CGLib动态代理

spring的AOP动态代理--JDK代理和CGLIB代理