Spring源码(15) -- Aop动态代理之 Enhancer

Enhancer 用途

Enhancer (增强器) 是标准Jdk动态代理的替代品,用于生成动态子类以启用方法拦截,还允许代理扩展具体的基类。

原始且最通用的回调类型是 MethodInterceptor(方法拦截器)。

通常,每个 Enhancer 都会使用一个 Callback 回调,但可以使用 callbackFilter 控制每个方法使用哪个回调。

此类最常见的用途体现在静态辅助方法中。

对于高级需求,例如自定义要使用的 ClassLoader,应该创建一个新的Enhancer实例。CGLIB中的其他类遵循类似的模式。

所有增强的对象都实现Factory接口,除非使用setUseFactory显式禁用此功能。

Factory接口提供了一个API来更改现有对象的回调,并提供了一种更快速、更简单的方法来创建相同类型的新实例。

几乎可以替代java.lang.reflect.Proxy 类。

源码

org.springframework.cglib.proxy.Enhancer

Callback[]

源码:org.springframework.cglib.proxy.Callback

Callback[] 是回调数组,是Enhancer的属性之一。

public interface Callback {
}

CallbackFilter

源码:org.springframework.cglib.proxy.CallbackFilter

CallbackFilter ,也是Enhancer的属性之一。

CallbackFilter 就是 CallBack 的过滤器,callbackFilter 可以控制每个方法使用哪个 Callback 回调。

可以重写 callbackFilter 接口,并实现 accept()方法。

public interface CallbackFilter {
    int accept(Method var1);

    boolean equals(Object var1);
}

Enhancer示例

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;

public class EnhancerDemo {

    public static class Target {
        public void printHello() {
            System.out.println("Hello World");
        }
    }

    public static void main(String[] param) {
        //Enhancer 是标准Jdk动态代理的替代品,用于生成动态子类以启用方法拦截,还允许代理扩展具体的基类。
        Target proxy = (Target) Enhancer.create(Target.class, (MethodInterceptor) (p, method, args, methodProxy) -> {
            System.out.println("before method.");
            
            //以下 p的值是 com.example.demo.sourceCode.cglib.CglibDemo$Target$$EnhancerByCGLIB$$87c3a731@27c60c
            // methodProxy的 fastClassInfo 有 f1为 class com.example.demo.sourceCode.cglib.CglibDemo$Target, 
            // f2为class com.example.demo.sourceCode.cglib.CglibDemo$Target$$EnhancerByCGLIB$$87c3a731
            
            Object result = methodProxy.invokeSuper(p, args);  
            System.out.println("after method.");
            return result;
        });

        proxy.printHello();

    }

}

Enhancer的 create()方法

create()方法,可以创建被拦截对象的辅助方法。

    public static Object create(Class type, Callback callback) {
        Enhancer e = new Enhancer();
        //要扩展的类或要实现的接口
        e.setSuperclass(type);
        //设置回调数组
        e.setCallback(callback);
        return e.create();
    }
    
    
    
    /**
     *  必要时生成一个新类,并使用指定的回调(如果有的话)创建一个新的对象实例。使用超类的无参数构造函数。
     */
      public Object create() {
          classOnly = false;
          argumentTypes = null;
          return createHelper();
      }
      
      
      private Object createHelper() {
          preValidate();
          Object key = KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
                  ReflectUtils.getNames(interfaces),
                  filter == ALL_ZERO ? null : new WeakCacheKey<CallbackFilter>(filter),
                  callbackTypes,
                  useFactory,
                  interceptDuringConstruction,
                  serialVersionUID);
          this.currentKey = key;
          
          //重点看这里, 调用了父类的 create() 方法
          Object result = super.create(key);
          return result;
    }
    
    

AbstractClassGenerator 的 create()

源码: org.springframework.cglib.core.AbstractClassGenerator#create

    protected Object create(Object key) {
        try {
          //获取类加载器
            ClassLoader loader = getClassLoader();
            Map<ClassLoader, ClassLoaderData> cache = CACHE;
            ClassLoaderData data = cache.get(loader);
            if (data == null) {
                synchronized (AbstractClassGenerator.class) {
                    cache = CACHE;
                    data = cache.get(loader);
                    if (data == null) {
                      //双重检查锁, 设置 ClassLoaderData。并设置缓存。
                        Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
                        data = new ClassLoaderData(loader);
                        newCache.put(loader, data);
                        CACHE = newCache;
                    }
                }
            }
            this.key = key;
            // 生成对象
            Object obj = data.get(this, getUseCache());
            if (obj instanceof Class) {
                return firstInstance((Class) obj);
            }
            return nextInstance(obj);
        }
        catch (RuntimeException | Error ex) {
            throw ex;
        }
        catch (Exception ex) {
            throw new CodeGenerationException(ex);
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值