Cglib动态代理,是Spring框架内给的一个代理模式, 由于jdk动态代理, 只能针对 有接口的对象, 而没有接口的对象则不能完成代理.
具体代码如下为 : 主要是针对 代理类进行改造, 实现MethodInterceptor 方法拦截器接口
注意导包!!!:
import org.springframework.cglib.proxy.MethodInterceptor;
public class CglibProxy implements MethodInterceptor{ private TxManager manager ; private Object target; public CglibProxy(TxManager manager, Object target) { this.manager = manager; this.target = target; } public Object createProxy(){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this); return enhancer.create(); } /** * * @param o proxy 获取的经过jdk代理后的对象 * @param method 反射方法对象 * @param objects 真实主题角色传入的参数 * @param methodProxy 反射方法代理对象 * @return 结果 * @throws Throwable 所有的错误 */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { Object result = null; try { if (StringUtils.endsWithIgnoreCase(method.getName(),"query")){ result = method.invoke(target, objects); }else{ manager.begin(); result = method.invoke(target, objects); manager.commit(); } } catch (Exception e) { manager.rollback(e); } finally { manager.release(); } return null; } }
调用的时候只要传入值,就行,特别方便, 创建的方法在源码底层有判断(无论是接口实现类还是普通类都可以):
private Object createHelper() { this.validate(); if (this.superclass != null) { this.setNamePrefix(this.superclass.getName()); } else if (this.interfaces != null) { this.setNamePrefix(this.interfaces[ReflectUtils.findPackageProtected(this.interfaces)].getName()); } return super.create(KEY_FACTORY.newInstance(this.superclass != null ? this.superclass.getName() : null, ReflectUtils.getNames(this.interfaces), this.filter, this.callbackTypes, this.useFactory, this.interceptDuringConstruction, this.serialVersionUID)); }
可以看到,这边在做判断,通过不同的方式创建代理
下面是测试方法
public static void main(String[] args) { OrderSerivceImpl orderService = new OrderSerivceImpl(); CglibProxy cglibProxy = new CglibProxy( new TxManager(),orderService); Order order = new Order(); order.setDate(new Date().toString()); order.setOperateName("zz"); order.setOrderId("111"); order.setProductName("可乐"); Object proxy = cglibProxy.createProxy(); System.out.println(proxy.getClass()); System.out.println("------------------"); if (proxy instanceof OrderService){ OrderService orderServiceProxy = (OrderService)proxy; orderServiceProxy.query("aaa"); orderServiceProxy.save(order); } }
结果如下:
不过使用spring的MethodInterceptor其实代理的也很麻烦用aop的思想玩起来是最爽的, 直接分离了最关键的一步, 详情请看我的博客 Spring Aop (MethodInterceptor) (企业实战)