🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 简介 在Java里面,我们要产生某个对象的代理对象,这个对象必须要有一个特点,即这个对象必须实现一个接口,动态代理技术只能基于接口进行代理。有时候我们在做开发的时候,这个对象就没有实现接口,有人可能会说,它既然没有接口,那我就给它定义一个接口,这是不行的,因为有时候我们拿到一个对象,而这个对象是服务器产生给我们的,是服务器提供给我们的,又不是我们自己写的,动不动就给它定义一个接口,是不行的. CGLIB了,这套API,即使没有接口,它也可以帮我们产生这个对象的代理对象。它的内部是怎么去产生这个对象的代理对象的呢?——实际上产生的是这个对象的子类,也即我们把一个对象交给CGLIB,它返回出来的似乎是一个代理对象(但它不是要产生一个对象的代理对象),但其实这个代理对象就是这个对象的子类,利用子类的方式来创建代理对象。在Spring里面就是这样做的,Spring里面有一个AOP编程(即面向切面编程,说白了就是动态代理,我们经常会交给Spring一个对象,它就会返回代理对象给我们,它在返回代理对象的时候,首先会检查我们这个对象有没有实现一个接口,如果我们这个类有接口,它使用Java的动态代理技术来帮我们构建出代理对象;如果我们这个类没有实现接口,它会使用CGLIB这套API,采用创建子类的方式来创建代理对象) # 例子 写一个类,一些类还是用上面的aop的 ~~~ package proxy; import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import service.UserService; import service.UserServiceImpl; public class UserServiceProxyFactory2 implements MethodInterceptor { /** * 代理的目标对象 */ private Object targetObject; public Object getObjectProxy(Object targetObject) { this.targetObject = targetObject; // 帮我们生成代理对象 Enhancer en = new Enhancer(); // 告诉他被代理对象,设置对谁进行代理,设置目标类为代理对象的父类 en.setSuperclass(this.targetObject.getClass()); // 代理要做什么,设置回调用对象为本身 en.setCallback(this); // 创建代理对象 return en.create(); } /** * 第一个参数 被代理原始对象 * 第二个参数 被代理对象的方法 * 第三个参数 运行期参数 * 第四个参数 代理方法对象 */ @Override public Object intercept(Object proxyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable { // 打开事务 System.out.println("打开事务"); // 调用原有方法 Object returnValue = methodProxy.invokeSuper(proxyobj, arg); // 提交事务 System.out.println("提交事务事务"); return returnValue; } } ~~~ 测试方法 ~~~ @Test public void index() { UserServiceProxyFactory2 factory = new UserServiceProxyFactory2(); UserService usProxy = (UserService) factory.getObjectProxy(new UserServiceImpl()); usProxy.save(); // 判断代理对象是否属于被代理对象 System.out.println(usProxy instanceof UserServiceImpl); } ~~~