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动态代理的主要内容,如果未能解决你的问题,请参考以下文章
Spring读源码系列之AOP--06---AopProxy===>spring使用jdk和cglib生成代理对象的终极奥义