18_CGLib动态代理
【概述】
已知JDK动态代理中的Proxy.newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)方法的第二个参数Class[] interfaces就是需要代理类实例实现的接口列表,即这里的代理类必须实现接口。
CGLib采用非常底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,并顺势织入横切逻辑。采用CGLib可以为任何类创建织入横切代码的代理创建器。
【例子】(注意cglib-2.1.3版本,使用cglib-2.2会出错)
【Monitor.java】
package com.Higgin.demo; /** * 监测类 */ public class Monitor { public static void begin(){ System.out.println("【操作数据库前】开始监测..."); } public static void end(){ System.out.println("【操作数据库后】结束检测,得到检测数据..."); } }
【PersonDap.java】
package com.Higgin.demo; /** * 操作数据库的PersonDao类 */ public class PersonDao { public void getAllPerson(){ System.out.println("查询数据库得到所有的Person"); } public void deleteAllPerson(){ System.out.println("删除数据库所有的Person"); } }
【CglibProxy.java】
package com.Higgin.demo; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor{ private Enhancer enhancer=new Enhancer(); public Object getProxy(Class clazz){ enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } /** * intercept方法会拦截目标类所有方法的调用 * obj: 目标类的实例 * method: 目标类方法的反射对象 * args: 方法的动态参数 * proxy: 代理类的实例 */ @Override public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable { Monitor.begin(); Object result=proxy.invokeSuper(obj, args); //通过代理类调用父类中的方法 Monitor.end(); return result; } }
【TestPersonDao.java】
package com.Higgin.demo; public class TestPersonDao { public static void main(String[] args) { CglibProxy proxy=new CglibProxy(); //可以通过getProxy(Class clazz)为一个目标类Proxy创建动态代理对象 PersonDao personDao=(PersonDao) proxy.getProxy(PersonDao.class); personDao.getAllPerson();
System.out.println("--------------------------------------")
personDao.deleteAllPerson(); } }
【运行结果】