Cglib动态代理源码分析

public class MyTest {
    public static void main(String[] args) {
        //动态代理创建的class文件存储到本地
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"d:\\code");
        //通过cglib动态代理获取代理对象的过程,创建调用的对象,在后续创建过程中EnhanceKey的对象,所以在进行enhancer对象创建的时候需要把EnhancerKey(newInstance)对象准备好,恰好这个对象也需要动态代理来生成
        Enhancer enhancer = new Enhancer();
        //设置enhancer对象的父类
        enhancer.setSuperclass(MyCalculator.class);
        //设置enhancer的回调对象
        enhancer.setCallback(new MyCglib());
        //创建代理对象
        MyCalculator myCalculator = (MyCalculator) enhancer.create();
        //通过代理对象调用目标方法
        myCalculator.add(1,1);
        System.out.println(myCalculator.getClass());
    }
}

一 创建EnHancer对象

创建EnHacner对象时,发现EnHancer有父类对象AbstractClassGenerator,优先完成父类对象的加载

二 加载AbstractClassGenerator对象 

在AbstractClassGenerator类中有一个内部类ClassLoaderData,里面有两个重要的回调函数GET_KEY 和load,一个用来把当前创建的代理对象名称存储为全局变量,一个用来生成代理对象的Class类

	protected static class ClassLoaderData {

		private final Set<String> reservedClassNames = new HashSet<String>();

		/**
		 * {@link AbstractClassGenerator} here holds "cache key" (e.g. {@link org.springframework.cglib.proxy.Enhancer}
		 * configuration), and the value is the generated class plus some additional values
		 * (see {@link #unwrapCachedValue(Object)}.
		 * <p>The generated classes can be reused as long as their classloader is reachable.</p>
		 * <p>Note: the only way to access a class is to find it through generatedClasses cache, thus
		 * the key should not expire as long as the class itself is alive (its classloader is alive).</p>
		 */
		private final LoadingCache<AbstractClassGenerator, Object, Object> generatedClasses;

		/**
		 * Note: ClassLoaderData object is stored as a value of {@code WeakHashMap<ClassLoader, ...>} thus
		 * this classLoader reference should be weak otherwise it would make classLoader strongly reachable
		 * and alive forever.
		 * Reference queue is not required since the cleanup is handled by {@link WeakHashMap}.
		 */
		private final WeakReference<ClassLoader> classLoader;

		private final Predicate uniqueNamePredicate = new Predicate() {
			public boolean evaluate(Object name) {
				return reservedClassNames.contains(name);
			}
		};

		private static final Function<AbstractClassGenerator, Object> GET_KEY = new Function<AbstractClassGenerator, Object>() {
			public Object apply(AbstractClassGenerator gen) {
				return gen.key;
			}
		};

		public ClassLoaderData(ClassLoader classLoader) {
			// 判断类加载器不能为空
			if (classLoader == null) {
				throw new IllegalArgumentException("classLoader == null is not yet supported");
			}
			// 设置类加载器,弱引用 即在下次垃圾回收时就会进行回收
			this.classLoader = new WeakReference<ClassLoader>(classLoader);
			// 新建一个回调函数,这个回调函数的作用在于缓存中没获取到值时,调用传入的生成的生成代理类并返回
			Function<AbstractClassGenerator, Object> load =
					new Function<AbstractClassGenerator, Object>() {
						public Object apply(AbstractClassGenerator gen) {
							Class klass = gen.generate(ClassLoaderData.this);
							return gen.wrapCachedClass(klass);
						}
					};
			// 为这个ClassLoadData新建一个缓存类
			generatedClasses = new LoadingCache<AbstractClassGenerator, Object, Object>(GET_KEY, load);
		}

		public ClassLoader getClassLoader() {
			return classLoader.get();
		}

		public void reserveName(String name) {
			reservedClassNames.add(name);
		}

		public Predicate getUniqueNamePredicate() {
			return uniqueNamePredicate;
		}

		public Object get(AbstractClassGenerator gen, boolean useCache) {
			// 如果不用缓存(默认使用)
			if (!useCache) {
				// 则直接调用生成器的命令
				return gen.generate(ClassLoaderData.this);
			}
			else {
				// 传入代理类生成器 并根据代理类生成器获取值返回
				Object cachedValue = generatedClasses.get(gen);
				// 解包装并返回
				return gen.unwrapCachedValue(cachedValue);
			}
		}
	}

三、EnhancerKey对象的创建

Cglib动态代理需要一个Enhancer增强器,在new Enhancer对象时会创建EnhancerKey对象,EnhancerKey是一个内部接口,里面的newInstance方法在创建我们的代理对象时会用到,所以需要优先创建一个EnhancerKey代理对象

public interface EnhancerKey {

		public Object newInstance(String type,
				String[] interfaces,
				WeakCacheKey<CallbackFilter> filter,
				Type[] callbackTypes,
				boolean useFactory,
				boolean interceptDuringConstruction,
				Long serialVersionUID);
	}
private static final EnhancerKey KEY_FACTORY =
			(EnhancerKey) KeyFactory.create(EnhancerKey.class, KeyFactory.HASH_ASM_TYPE, null);

public static KeyFactory create(ClassLoader loader, Class keyInterface, KeyFactoryCustomizer customizer,
			List<KeyFactoryCustomizer> next) {
		// 创建一个最简易的代理类生成器 即只会生成HashCode equals toString newInstance方法
		Generator gen = new Generator();
		// 设置接口为enhancerKey类型
		gen.setInterface(keyInterface);
		// SPRING PATCH BEGIN
		gen.setContextClass(keyInterface);
		// SPRING PATCH END

		if (customizer != null) {
			// 添加定制器
			gen.addCustomizer(customizer);
		}
		if (next != null && !next.isEmpty()) {
			for (KeyFactoryCustomizer keyFactoryCustomizer : next) {
				// 添加定制器
				gen.addCustomizer(keyFactoryCustomizer);
			}
		}
		// 设置生成器的类加载器
		gen.setClassLoader(loader);
		// 生成enhancerKey的代理类
		return gen.create();
	}

调用AbstractClassGenerator的create方法,Enhancer继承了AbstractClassGenerator,在创建Enhancer时优先设置了GET_KEY变量,这个函数接口会在后期调用,给全局变量设置下当前生成代理类的全路径名称

		private static final Function<AbstractClassGenerator, Object> GET_KEY = new Function<AbstractClassGenerator, Object>() {
			public Object apply(AbstractClassGenerator gen) {
				return gen.key;
			}
		};
	protected Object create(Object key) {
		try {
			// 获取到当前生成器的类加载器
			ClassLoader loader = getClassLoader();
			// 当前类加载器对应的缓存  缓存key为类加载器,缓存的value为ClassLoaderData,可以理解为一个缓存对象,只不过此缓存对象中包含的是具体的业务逻辑处理过程,有两个function的函数式接口,一个是返回gen.key,对应的名称叫GET_KEY,还有一个是为了创建具体的class,名字叫做load
			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) {
						// 新建一个缓存Cache,并将之前的缓存Cache的数据添加进来,并将已经被gc回收的数据给清除掉
						Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
						// 新建一个当前加载器对应的ClassLoaderData并加到缓存中,但ClassLoaderData中此时还没有数据
						data = new ClassLoaderData(loader);
						newCache.put(loader, data);
						// 刷新全局缓存
						CACHE = newCache;
					}
				}
			}
			// 设置一个全局key
			this.key = key;
			// 在刚创建的data(ClassLoaderData)中调用get方法 并将当前生成器,
			// 以及是否使用缓存的标识穿进去 系统参数 System.getProperty("cglib.useCache", "true")
			// 返回的是生成好的代理类的class信息
			Object obj = data.get(this, getUseCache());
			// 如果为class则实例化class并返回我们需要的代理类
			if (obj instanceof Class) {
				return firstInstance((Class) obj);
			}
			// 如果不是则说明是实体,则直接执行另一个方法返回实体
			return nextInstance(obj);
		}
		catch (RuntimeException | Error ex) {
			throw ex;
		}
		catch (Exception ex) {
			throw new CodeGenerationException(ex);
		}
	}

在create方法里面调用内部类ClassLoaderData的构造方法

		public ClassLoaderData(ClassLoader classLoader) {
			// 判断类加载器不能为空
			if (classLoader == null) {
				throw new IllegalArgumentException("classLoader == null is not yet supported");
			}
			// 设置类加载器,弱引用 即在下次垃圾回收时就会进行回收
			this.classLoader = new WeakReference<ClassLoader>(classLoader);
			// 新建一个回调函数,这个回调函数的作用在于缓存中没获取到值时,调用传入的生成的生成代理类并返回
			Function<AbstractClassGenerator, Object> load =
					new Function<AbstractClassGenerator, Object>() {
						public Object apply(AbstractClassGenerator gen) {
							Class klass = gen.generate(ClassLoaderData.this);
							return gen.wrapCachedClass(klass);
						}
					};
			// 为这个ClassLoadData新建一个缓存类
			generatedClasses = new LoadingCache<AbstractClassGenerator, Object, Object>(GET_KEY, load);
		}

在generatedClasses里存入两个函数式接口,GET_KEY是返回当前生成代理类的全路径名称,load是生成代理class类

Object obj = data.get(this, getUseCache());

在之前只是存入了两个函数式接口,并没有进行调用,在data.get方法里完成具体的调用,load回调函数里通过Class klass = gen.generate(ClassLoaderData.this)完成EnHancerKey的Class对象的创建

		public Object get(AbstractClassGenerator gen, boolean useCache) {
			// 如果不用缓存(默认使用)
			if (!useCache) {
				// 则直接调用生成器的命令
				return gen.generate(ClassLoaderData.this);
			}
			else {
				// 传入代理类生成器 并根据代理类生成器获取值返回
				Object cachedValue = generatedClasses.get(gen);
				// 解包装并返回
				return gen.unwrapCachedValue(cachedValue);
			}
		}
    public V get(K key) {
        KK cacheKey = this.keyMapper.apply(key);
        Object v = this.map.get(cacheKey);
        return v != null && !(v instanceof FutureTask) ? v : this.createEntry(key, cacheKey, v);
    }

    protected V createEntry(final K key, KK cacheKey, Object v) {
        boolean creator = false;
        FutureTask task;
        Object result;
        if (v != null) {
            task = (FutureTask)v;
        } else {
            task = new FutureTask(new Callable<V>() {
                public V call() throws Exception {
                    return LoadingCache.this.loader.apply(key);
                }
            });
            result = this.map.putIfAbsent(cacheKey, task);
            if (result == null) {
                creator = true;
                task.run();
            } else {
                if (!(result instanceof FutureTask)) {
                    return result;
                }

                task = (FutureTask)result;
            }
        }

        try {
            result = task.get();
        } catch (InterruptedException var9) {
            throw new IllegalStateException("Interrupted while loading cache item", var9);
        } catch (ExecutionException var10) {
            Throwable cause = var10.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException)cause;
            }

            throw new IllegalStateException("Unable to load cache item", cause);
        }

        if (creator) {
            this.map.put(cacheKey, result);
        }

        return result;
    }

调用两个回调方法,完成全局变量的赋值以及Class对象的创建,然后返回到firstInstance方法调用ReflectUtils.newInstance转为object对象,当完成了Enhancerkey对象的创建后才可以创建我们自己的代理对象

四、创建代理对象

//创建代理对象
MyCalculator myCalculator = (MyCalculator) enhancer.create();
  public Object create() {
        this.classOnly = false;
        this.argumentTypes = null;
        return this.createHelper();
    }
private Object createHelper() {
		// 校验callbackTypes、filter是否为空,以及为空时的处理
		preValidate();
		// 通过newInstance方法来创建EnhancerKey对象,正常情况下,只需要new一个对象就可以调用方法了,但是Key_Factory是一个EnhancerKey类型,是一个内部接口,需要动态代理来实现,最终是为了调用newInstance方法
		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);
		// 设置当前enhancer的代理类的key标识
		this.currentKey = key;
		// 调用父类即AbstractClassGenerator的创建代理类
		Object result = super.create(key);
		return result;
	}

调用super.create时又回到之前创建代理对象EnhancerKey的create方法,此时CACHE缓存对象已经在创建EnhancerKey代理对象时完成了赋值,所以直接调用data.get完成我们本身的代理对象创建,到这一步和之前创建EnhancerKey代理对象的逻辑一样

	protected Object create(Object key) {
		try {
			// 获取到当前生成器的类加载器
			ClassLoader loader = getClassLoader();
			// 当前类加载器对应的缓存  缓存key为类加载器,缓存的value为ClassLoaderData,可以理解为一个缓存对象,只不过此缓存对象中包含的是具体的业务逻辑处理过程,有两个function的函数式接口,一个是返回gen.key,对应的名称叫GET_KEY,还有一个是为了创建具体的class,名字叫做load
			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) {
						// 新建一个缓存Cache,并将之前的缓存Cache的数据添加进来,并将已经被gc回收的数据给清除掉
						Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
						// 新建一个当前加载器对应的ClassLoaderData并加到缓存中,但ClassLoaderData中此时还没有数据
						data = new ClassLoaderData(loader);
						newCache.put(loader, data);
						// 刷新全局缓存
						CACHE = newCache;
					}
				}
			}
			// 设置一个全局key
			this.key = key;
			// 在刚创建的data(ClassLoaderData)中调用get方法 并将当前生成器,
			// 以及是否使用缓存的标识穿进去 系统参数 System.getProperty("cglib.useCache", "true")
			// 返回的是生成好的代理类的class信息
			Object obj = data.get(this, getUseCache());
			// 如果为class则实例化class并返回我们需要的代理类
			if (obj instanceof Class) {
				return firstInstance((Class) obj);
			}
			// 如果不是则说明是实体,则直接执行另一个方法返回实体
			return nextInstance(obj);
		}
		catch (RuntimeException | Error ex) {
			throw ex;
		}
		catch (Exception ex) {
			throw new CodeGenerationException(ex);
		}
	}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring动态代理主要是通过JDK动态代理CGLIB动态代理两种方式实现的。其中,JDK动态代理是基于接口的代理,而CGLIB动态代理则是基于类的代理。 在使用JDK动态代理时,Spring会根据目标对象实现的接口来创建代理对象。具体实现过程如下: 1. 创建一个实现InvocationHandler接口的代理处理器对象,该对象负责实际的代理操作。 2. 调用Proxy类的静态方法newProxyInstance()来创建代理对象。该方法需要传入三个参数:ClassLoader对象、目标对象实现的接口列表以及代理处理器对象。 3. 当调用代理对象的方法时,实际上是调用了InvocationHandler接口的invoke()方法,该方法会根据传入的Method对象和参数列表来执行目标对象的方法。 而在使用CGLIB动态代理时,Spring会通过ASM字节码框架来生成一个子类,并重写其中的方法来实现代理。具体实现过程如下: 1. 创建一个Enhancer对象,该对象负责生成子类。 2. 设置父类和回调函数。父类即为目标对象,回调函数即为MethodInterceptor接口的实现类,该类负责实际的代理操作。 3. 调用Enhancer对象的create()方法来创建代理对象。该方法会生成一个子类,并重写其中的方法来实现代理。 4. 当调用代理对象的方法时,实际上是调用了MethodInterceptor接口的intercept()方法,该方法会根据传入的Method对象和参数列表来执行目标对象的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值