JDK dynamic proxy and CGLib dynamic proxy

    The JDK dynamic proxy is that the JVM dynamically creates the proxy object of the object and returns it according to the incoming object.
    CGLib dynamic proxy is more complicated, it implements class proxy through inheritance .

JDK dynamic proxy

Implementation steps:

  1. Define business interface
  2. Implement business interface
  3. define proxy class
public class JDKProxy {
    /**
     * @param obj
     *            需要代理的对象
     * @return 返回代理对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T proxy(final T obj) {
        return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * proxy: method:被代理对象的方法 args:被代理对象的方法需要的参数
                     */
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 增强逻辑
                        // 调用原方法
                        Object result = method.invoke(obj, args);
                        // 增强逻辑
                        return result;
                    }
                });
    }
}

CGLib dynamic proxy

principle:

  1. custom class A
  2. Use CGLib to create a dynamic class B with no name in memory, returning a reference to B of C
  3. Specify the inheritance structure of A and B by referencing C, B extends A
  4. Define method call interception, enhance logic in interception, and perform original operation
public class CGLibProxy {
    @SuppressWarnings("unchecked")
    public static <T> T proxy(Class<T> clazz) {
        // 在内存中创建动态类
        Enhancer dynamicClass = new Enhancer();
        // 设置动态类的父类
        dynamicClass.setSuperclass(clazz);
        // 创建方法调用拦截
        Callback callback = new MethodInterceptor() {
            /**
             * proxy:代理对象
             * method:被拦截的方法对象
             * args:方法参数
             * methodProxy:被拦截的方法对象的代理对象
             */
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)
                    throws Throwable {
                // 增强逻辑
                // 调用父类的方法,由于继承重写的特性,最终会执行子类的方法
                // 不使用这个方法:methodProxy.invoke(proxy, args);
                Object result = methodProxy.invokeSuper(proxy, args);
                // 增强逻辑
                return result;
            }
        };
        dynamicClass.setCallback(callback);
        // 返回动态类实例
        return (T) dynamicClass.create();
    }
}

    How to understand the implementation of CGLib dynamic proxy?

// 例如:Student extends Person
// 创建 Student 对象,但以 Person 展现
Person p = new Student();
// 我们知道,如果 Person 中没有 speak()方法,那么这里编译不会通过
// 程序运行时,并不会调用 Person 中 speak()方法的实现,而是调用 Student 中的实现
p.speak();

// 从继承和重写上看,我们应该知道为什么在 CGLib 中
// 不使用这个方法:methodProxy.invoke(proxy, args);
// 而调用 invokeSuper 方法的原因
Object result = methodProxy.invokeSuper(proxy, args);

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324647385&siteId=291194637