AOP详解-CGLIB动态代理

165 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情

spring的代理又可以分为JDK动态代理和CGLIB代理。之前谢过了JDK动态代理,这篇主要分析CGLIB代理,围绕CglibAopProxy展开。

CGLib的动态代理

还有一个叫CGLib的动态代理,和JDK动态代理相比较:JDK创建代理有一个限制,就是只能为接口创建代理实例,而对于没有通过接口定义业务方法的类,则可以通过CGLib创建动态代理.

代码示例

创建接口


public interface Subject {
    void request();
    void hello();
}



创建目标对象

public class RealSubject implements Subject {
    public void request() {
        System.out.println("real subject execute request..");
    }
    public void hello() {
        System.out.println("real subject execute hello..");
    }
}

创建代理对象


public class CglibProxyInterceptor implements MethodInterceptor {
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    
        Object result = null;
        try {
            result = methodProxy.invokeSuper(o, objects);

        } catch (Exception e) {
            throw e;
        } 
        return result;
    }

过程分析

image.png

CGLIB代理主要是由CglibAopProxy完成,从其getProxy方法入手,进行分析,CGLIB是通过生成被代理的子类 完成动态代理的,通过this.advised.addInterface(additionalInterface) 添加代理类实现的接口;

创建并配置 Enhance,在为Enhancer设置拦截器链时,代码 enhancer.setCallbackFilter(new ProxyCallbackFilter(...)); ,封装了ProxyCallbackFilter,它实现了CallBackFilter接口.

在ProxyCallbackFilter中也提到使用AOP_PROXY实际上就是DynamicAdvisedInterceptor。DynamicAdvisedInterceptor实现了MethodInterceotor方法

JDK动态代理和CGLib的比较

JDK代理使用的是反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。 CGLIB代理使用字节码处理框架asm,对代理对象类的class文件加载进来,通过修改字节码生成子类。

JDK创建代理对象效率较高,执行效率较低; CGLIB创建代理对象效率较低,执行效率高。

JDK动态代理机制是委托机制,只能对实现接口的类生成代理,通过反射动态实现接口类; CGLIB则使用的继承机制,针对类实现代理,被代理类和代理类是继承关系。