Java CGLIB动态代理

Jakcy Java 2021-10-28 9

原理

CGLIB代理通过Enhancer来指定要代理的目标对象、实际处理代理逻辑的对象,最终通过调用create()方法得到代理对象,对这个对象 所有非final方法 的调用都会转发给MethodInterceptor.intercept()方法,在intercept()方法里我们可以加入任何逻辑,比如修改方法参数,加入日志功能、安全检查功能等; 通过调用MethodProxy.invokeSuper()方法,将调用转发给原始对象,具体到本例,就是Hello的具体方法。CGLIG中MethodInterceptor的作用跟JDK代理中的InvocationHandler很类似,都是方法调用的中转站。

代码

package com.yixing.demo;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class Demo2 {

    static class Hello {

        public void say() {
            System.out.println("Hello");
        }
    }

    static class DemoProxy implements MethodInterceptor {

        /**
         * 根据类获取代理对象
         */
        public static Hello createObject(Class<Hello> helloClass) {
            Enhancer enhancer = new Enhancer();
            // 设置被代理的类
            enhancer.setSuperclass(helloClass);
            // 设置代理类
            enhancer.setCallback(new DemoProxy());
            // 创建代理对象
            return (Hello) enhancer.create();
        }


        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

            try {
                System.out.println(obj.getClass());
                System.out.println(obj.getClass().getSuperclass());
                Arrays.stream(obj.getClass().getInterfaces()).forEach(System.out::println);
                System.out.println("begin method " + method.getName());
                return proxy.invokeSuper(obj, args);
            } finally {
                System.out.println("end");
            }
        }


    }

    public static void main(String[] args) {
        Hello hello = new Hello();
        hello.say();
        Hello hello2 = DemoProxy.createObject(Hello.class);
        hello2.say();
    }

}

Hello
class com.yixing.demo.Demo2$Hello$$EnhancerByCGLIB$$4454f6d7
class com.yixing.demo.Demo2$Hello
interface net.sf.cglib.proxy.Factory
begin method say
Hello
end

生成的代理类

public class Demo2$Hello$$EnhancerByCGLIB$$e3734e52
  extends Demo2$Hello
  implements Factory
{
  ...
  private MethodInterceptor CGLIB$CALLBACK_0; // ~~
  ...
  
  public final String say()
  {
    ...
    MethodInterceptor tmp17_14 = CGLIB$CALLBACK_0;
    if (tmp17_14 != null) {
	  // 将请求转发给MethodInterceptor.intercept()方法。
      return (String)tmp17_14.intercept(this, 
              CGLIB$say$0$Method, 
              new Object[] {}, 
              CGLIB$say$0$Proxy);
    }
    return super.sayHello(paramString);
  }
  ...
}