CGLIB,这套API,即使没有接口,它也可以帮我们产生这个对象的代理对象。
它的内部是怎么去产生这个对象的代理对象的呢?
- ——实际上产生的是这个对象的子类,也即我们把一个对象交给CGLIB,它返回出来的似乎是一个代理对象(但它不是要产生一个对象的代理对象),但其实这个代理对象就是这个对象的子类,利用子类的方式来创建代理对象。
- 在Spring里面就是这样做的,Spring里面有一个AOP编程(即面向切面编程,说白了就是动态代理,我们经常会交给Spring一个对象,它就会返回代理对象给我们,它在返回代理对象的时候,首先会检查我们这个对象有没有实现一个接口,如果我们这个类有接口,它使用Java的动态代理技术来帮我们构建出代理对象;如果我们这个类没有实现接口,它会使用CGLIB这套API,采用创建子类的方式来创建代理对象)
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();}/*** 第一个参数 被代理原始对象* 第二个参数 被代理对象的方法* 第三个参数 运行期参数* 第四个参数 代理方法对象*/@Overridepublic 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);
}