Java的CGLIB
CGLIB
规则:
-
目标对象:
不能是final类;
存在public的构造器;代理创建的目标代理对象需要与public构造器的参数相匹配。
需要进行增强功能的方法不能是final;
cglib创建代理对象,对方法进行增强
public class HelloWorldCglib { private String field; public HelloWorldCglib() { } public HelloWorldCglib(String field) { this.field = field; } public void print() { System.out.println("hello world cglib"); } } public class HelloWorldCglibInvocate implements MethodInterceptor { /** * * @param o * 目标代理对象 * @param method * 目标方法 * @param objects * 目标方法参数 * @param methodProxy * 方法代理对象 */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("hello world proxy before"); Object obj = methodProxy.invokeSuper(o, objects); System.out.println("hello world proxy after"); return obj; } } public class ReflectApplication { public static void main(String[] args) throws Exception { // 设置该属性,是为了生成代理对象的.class类文件 path是类文件存在的位置 System.setProperty("cglib.debugLocation", "path"); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(HelloWorldCglib.class); enhancer.setCallback(new HelloWorldCglibInvocate()); // 创建的代理对象,需要与public构造器参数相匹配 HelloWorldCglib proxy1 = (HelloWorldCglib) enhancer.create(); HelloWorldCglib proxy2 = (HelloWorldCglib) enhancer.create(new Class[] {String.class}, new Object[] {"hello"}); proxy1.print(); System.out.println("-------------------"); proxy2.print(); } } // 结果 hello world proxy before hello world cglib hello world proxy after ------------------- hello world proxy before hello world hello cglib hello world proxy after
CGLIB是根据Enhancer根据目标对象(Target,非final类),创建一个目标对象代理类(TargetProxy)。目标对象(Target)作为目标对象代理类(TargetProxy)的父类,TargetProxy重写了Target的所有非final方法。Enhancer为TargetProxy设置了增强功能的CallBack类,最终每当代理类调用代理方法时,都调用CallBack.intercept方法,实现代理功能。
public class HelloWorldCglib { public HelloWorldCglib() { } public String print2() { return "print2"; } public String print3() { return "print3"; } public String print4() { return "print4"; } } public class HelloWorldCglibInvocate implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("hello world proxy"); return methodProxy.invokeSuper(o, objects); } } // 不管原方法返回任何值,该回调会返回固定值 public class HelloWorldFixedValueInvocate implements FixedValue { @Override public Object loadObject() throws Exception { return "fixed value"; } } // 方法拦截,返回的结果是回调数组的下标 public class HelloWorldCglibMethodFilter implements CallbackFilter { @Override public int accept(Method method) { switch (method.getName()) { case "print2": return 0; case "print3": return 1; case "print4": return 2; } return 0; } } public class ReflectApplication { public static void main(String[] args) throws Exception { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(HelloWorldCglib.class); enhancer.setCallback(new HelloWorldCglibInvocate()); // 回调数组,方法回调拦截器返回的结果,对应该数组下标index // NoOp.INSTANCE 不作任何增强处理 Callback[] callbacks = new Callback[] {new HelloWorldCglibInvocate(), new HelloWorldFixedValueInvocate(), NoOp.INSTANCE}; enhancer.setCallbacks(callbacks); // 方法回调拦截器 enhancer.setCallbackFilter(new HelloWorldCglibMethodFilter()); HelloWorldCglib proxy1 = (HelloWorldCglib) enhancer.create(); System.out.println(proxy1.print2()); System.out.println("-------------------"); System.out.println(proxy1.print3()); System.out.println("-------------------"); System.out.println(proxy1.print4()); } } // 结果 hello world proxy print2 ------------------- fixed value ------------------- print4
Dispatch:回调类,每次访问对象属性(调用getter和setter方法)时都会被触发代理类回调方法。
LazyLoader:回调类,第一次访问对象属性(调用getter方法)时被触发代理类回调方法。
public class HelloWorldCglib { private String field; public HelloWorldCglib() { } public String getField() { return field; } public void setField(String field) { this.field = field; } } public class HelloWorldCglibDispatch implements Dispatcher { @Override public Object loadObject() throws Exception { System.out.println("dispatcher before"); HelloWorldCglib obj = new HelloWorldCglib(); obj.setField("dispatcher"); System.out.println("dispatcher after"); return obj; } } public class HelloWorldCglibLazyLoader implements LazyLoader { @Override public Object loadObject() throws Exception { System.out.println("lazy loader before"); HelloWorldCglib obj = new HelloWorldCglib(); obj.setField("lazy loader"); System.out.println("lazy loader after"); return obj; } } public class ReflectApplication { public static void main(String[] args) throws Exception { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(HelloWorldCglib.class); enhancer.setCallback(new HelloWorldCglibLazyLoader()); HelloWorldCglib lazyProxy = (HelloWorldCglib) enhancer.create(); lazyProxy.setField("origin lazy"); System.out.println(lazyProxy.getField()); System.out.println("==================="); lazyProxy.setField("origin 2 lazy"); System.out.println(lazyProxy.getField()); System.out.println("-------------------"); Enhancer enhancer2 = new Enhancer(); enhancer2.setSuperclass(HelloWorldCglib.class); enhancer2.setCallback(new HelloWorldCglibDispatch()); HelloWorldCglib dispatcherProxy = (HelloWorldCglib) enhancer2.create(); dispatcherProxy.setField("origin dispatcher"); System.out.println(dispatcherProxy.getField()); System.out.println("==================="); dispatcherProxy.setField("origin 2 dispatcher"); System.out.println(dispatcherProxy.getField()); } } // 结果 lazy loader before lazy loader after origin lazy =================== origin 2 lazy ------------------- dispatcher before dispatcher after dispatcher before dispatcher after dispatcher =================== dispatcher before dispatcher after dispatcher before dispatcher after dispatcher