Spring(二十)Spring AOP createProxy 创建CGLIB代理 过程-下篇

上篇文章分析了CGLIB创建代理的逻辑结构,但是感觉CGLIB比JDK生成代理复杂很多,而且上篇文章没有深入,本文将深入了解 CGLIB创建过程,本文包含包含CGLIB创建代理的逻辑代码有点多,但是确实复杂!
总不能Spring 替我们生成了类,而我们不知道它具体长啥样子吧。

Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
此为Spring中代理方法创建入口。

CglibAopProxy

直接进入CglibAopProxy主工具类,入口是 getProxy 方法:

	@Override
	public Object getProxy(@Nullable ClassLoader classLoader) {
		if (logger.isTraceEnabled()) {
			logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
		}

		try {
		// advised 为一个辅助类,里面包含了当前该bean类所命中的所有advice等,rootClass即代理原始类。
			Class<?> rootClass = this.advised.getTargetClass();
			Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
			// 以当前rootClass为父类进行创建
			Class<?> proxySuperClass = rootClass;
			if (ClassUtils.isCglibProxyClass(rootClass)) {
				proxySuperClass = rootClass.getSuperclass();
				Class<?>[] additionalInterfaces = rootClass.getInterfaces();
				for (Class<?> additionalInterface : additionalInterfaces) {
					this.advised.addInterface(additionalInterface);
				}
			}

			// Validate the class, writing log messages as necessary.
			// 验证当前类,例如final类型方法无法创建代理,包可见的无法创建代理因为ClassLoader不同
			validateClassIfNecessary(proxySuperClass, classLoader);

			// 创建Enhancer并配置
			Enhancer enhancer = createEnhancer();
			if (classLoader != null) {
			 	// 设置classLoader
				enhancer.setClassLoader(classLoader);
				if (classLoader instanceof SmartClassLoader &&
						((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
					enhancer.setUseCache(false);
				}
			}
			// 设置父类,如果proxySuperClass 是接口,则会将其作为接口设置
			enhancer.setSuperclass(proxySuperClass);
			// 设置接口类,AopProxyUtils.completeProxiedInterfaces(this.advised) 中会获取所有匹配的接口类,以及其他类,例如 SpringProxy、Advised 	
			// DecoratingProxy 等
			enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
			// 设置Spring 生成代理的命名规则,就是我们所常见的 $$BySpringCGLIB 之类
			enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
			// 设置字节码生成策略器,这里设置为 ClassLoaderAwareUndeclaredThrowableStrategy,为对  DefaultGeneratorStrategy 一层封装
			enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
			// 获取各种回调
			Callback[] callbacks = getCallbacks(rootClass);
			// 设置callbacks的Class类型
			Class<?>[] types = new Class<?>[callbacks.length];
			for (int x = 0; x < types.length; x++) {
				types[x] = callbacks[x].getClass();
			}
			// fixedInterceptorMap only populated at this point, after getCallbacks call above
			// 设置CallBackFilter的值
			enhancer.setCallbackFilter(new ProxyCallbackFilter(
					this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
			enhancer.setCallbackTypes(types);

			// Generate the proxy class and create a proxy instance.
			return createProxyClassAndInstance(enhancer, callbacks);
		}
		catch (CodeGenerationException | IllegalArgumentException ex) {
			throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
					": Common causes of this problem include using a final class or a non-visible class",
					ex);
		}
		catch (Throwable ex) {
			// TargetSource.getTarget() failed
			throw new AopConfigException("Unexpected AOP exception", ex);
		}
	}

以下为总结核心步骤:

  1. 由于CGLIB是通过子类方式,故会获取当前代理类,并且会检查所有方法,对于final类型不能重写方法,会输出debug 类型日志。
  2. 设置Interfaces,会通过 AopProxyUtils.completeProxiedInterfaces(this.advised) ,利用 AdvisedSupport 获取该bean类型,所需要所有待实现的接口,通过配置可以加入 SpringProxyAdvisedDecoratingProxy等内置接口,当然也可以像jdk代理一样加入自定义接口。例如使用IntroductionAdvisor 拓展bean功能。
  3. 设置代理类命名模式SpringNamingPolicy 和 ClassLoader包装工具类ClassLoaderAwareUndeclaredThrowableStrategy
  4. 配置并设置回调类 Callback。最后主要会返回以下几种类型callback,可以理解为CGLIB代理类,代理各种方法策略:
		Callback[] mainCallbacks = new Callback[] {
				aopInterceptor,  // DynamicAdvisedInterceptor 类型,拦截正常 advice切面
				targetInterceptor,  // 直接调用方法,不走拦截器 invoke target without considering advice, if optimized
				new SerializableNoOp(),  // 没有重写任何方法,则会匹配该像no override for methods mapped to this
				targetDispatcher, 
				this.advisedDispatcher,
				new EqualsInterceptor(this.advised),  // 处理equals
				new HashCodeInterceptor(this.advised)  // 处理hashcode
		};
  1. 设置一个 ProxyCallbackFilter ,用于对 上述callbacks进行过滤,封装具体需要拦截的逻辑。
createProxyClassAndInstance

这样就会调用到了子类 ObjenesisCglibAopProxycreateProxyClassAndInstance 方法,实际上还是主要功能还是有Enhancer完成,因为Enhancer 负责画一个类,而Objenesis只是负责创建类实例。

		// Enhance 负责画一个类
		Class<?> proxyClass = enhancer.createClass();
		Object proxyInstance = null;

		if (objenesis.isWorthTrying()) {
			try {
				// 创建类实例
				proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
			}
			catch (Throwable ex) {
				logger.debug("Unable to instantiate proxy using Objenesis, " +
						"falling back to regular proxy construction", ex);
			}
		}
createClass

主要就来看Spring 集成的Cglib 是如何利用 Enhancer 和 ASM创建,来替我们创建一个代理类。

	public Class createClass() {
		classOnly = true;
		return (Class) createHelper();
	}

而后进入 createHelper:

	private Object createHelper() {
		// 前置验证callbackTypes 和 filter
		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;
		// 调用父类 AbstractClassGenerator 的create方法
		Object result = super.create(key);
		return result;
	}

本步包括以下几个步骤:

  1. 验证callbackTypes 和 filter
  2. 利用 代理类名字和回调callback创建包装类
  3. 调用父类 AbstractClassGenerator 的create方法
AbstractClassGenerator 的 create

看看create关键代码:

	protected Object create(Object key) {
		try {
			// 获取classloader
			ClassLoader loader = getClassLoader();
			Map<ClassLoader, ClassLoaderData> cache = CACHE;
			// 尝试从缓存中获取ClassLoader相关存储信息
			ClassLoaderData data = cache.get(loader);
			if (data == null) {
				synchronized (AbstractClassGenerator.class) {
					cache = CACHE;
					data = cache.get(loader);
					if (data == null) {
						Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
						data = new ClassLoaderData(loader);
						newCache.put(loader, data);
						CACHE = newCache;
					}
				}
			}
			this.key = key;
			// 将this穿进去,此时this就是Enhancer
			Object obj = data.get(this, getUseCache());
			if (obj instanceof Class) {
				return firstInstance((Class) obj);
			}
			return nextInstance(obj);
		}
		...
  1. 获取ClassLoader和 ClassLoaderData。
  2. 调用 ClassLoaderData,并调用其 get方法,传入当前实例即 Enhancer 和 代表是否用索引的useCache
    ClassLoaderData 的get方法:
		public Object get(AbstractClassGenerator gen, boolean useCache) {
			if (!useCache) {
				return gen.generate(ClassLoaderData.this);
			}
			else {
				Object cachedValue = generatedClasses.get(gen);
				return gen.unwrapCachedValue(cachedValue);
			}
		}

如果不使用缓存,则直接会调用 Enhancergenerate方法进行生成。
如果使用缓存,则会从 LoadingCache<AbstractClassGenerator, Object, Object> 获取,而最终也会通过 Enhancergenerate 创建。
LoadingCache 是Spring 通过字节码生成的。
LoadingCache 的get方法

    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);
    }

如果获取不到,则会进入createEntry进行创建:

    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进行使用
            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;
                // 调用run方法,即调用 `LoadingCache.this.loader.apply(key);` 方法
                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;
    }

上面主要有以下几个逻辑:

  1. 声明一个FutureTask进行代理类创建。
  2. key 其实就是 一个Enhancer类型
  3. 最终就是异步调用 LoadingCache.this.loader.apply(key); 方法,而LoadingCache的loader长这个样子:
		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) {
						// gen 就是Enhancer
							Class klass = gen.generate(ClassLoaderData.this);
							return gen.wrapCachedClass(klass);
						}
					};
			generatedClasses = new LoadingCache<AbstractClassGenerator, Object, Object>(GET_KEY, load);
		}

所以在异步方法中,其实就是调用 Enhancergenerate 方法。

Enhancer 的 generate

看Enhancer 的generate:

	@Override
	protected Class generate(ClassLoaderData data) {
		// 验证classOnly 和 callbacks等字段
		validate();
		if (superclass != null) {
		// 设置名字前缀
			setNamePrefix(superclass.getName());
		}
		else if (interfaces != null) {
			// 如果superClass == null,设置接口包可见的一个接口名字作为前缀
			setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName());
		}
		// 调用父类generate方法
		return super.generate(data);
	}

父类 AbstractClassGeneratorgenerate 方法:

	protected Class generate(ClassLoaderData data) {
		Class gen;
		Object save = CURRENT.get();
		// 设置当前执行threadlocal
		CURRENT.set(this);
		try {
			// 获取当前threadLoader
			ClassLoader classLoader = data.getClassLoader();
			if (classLoader == null) {
				throw new IllegalStateException("ClassLoader is null while trying to define class " +
						getClassName() + ". It seems that the loader has been expired from a weak reference somehow. " +
						"Please file an issue at cglib's issue tracker.");
			}
			synchronized (classLoader) {
				// 获取创建之后的class名字
				String name = generateClassName(data.getUniqueNamePredicate());
				data.reserveName(name);
				this.setClassName(name);
			}
			if (attemptLoad) {
			// 是否直接返回,没有封装回调及aop,只是用cglib生成一个对象。
				try {
					gen = classLoader.loadClass(getClassName());
					return gen;
				}
				catch (ClassNotFoundException e) {
					// ignore
				}
			}
			// 使用上面定义的策略即asm生成类的字节码
			byte[] b = strategy.generate(this);
			String className = ClassNameReader.getClassName(new ClassReader(b));
			ProtectionDomain protectionDomain = getProtectionDomain();
			synchronized (classLoader) { // just in case
				// SPRING PATCH BEGIN
				gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain, contextClass);
				// SPRING PATCH END
			}
			return gen;
		}
		catch (RuntimeException | Error ex) {
			throw ex;
		}
		catch (Exception ex) {
			throw new CodeGenerationException(ex);
		}
		finally {
			CURRENT.set(save);
		}
	}

上面有以下逻辑:

  1. 设置当前实例到CURRENT的ThreadLocal变量中。
  2. 通过ThreadLoader获取待生成的class名字。
  3. 判断是否是直接返回,直接返回就只是生成一个类实例,而不进行自定义aop或者其他代理逻辑构建。
  4. 进入上面传入的策略 ClassLoaderAwareUndeclaredThrowableStrategygenerate 进入生成字节码操作。
		public byte[] generate(ClassGenerator cg) throws Exception {
			if (this.classLoader == null) {
				return super.generate(cg);
			}

			Thread currentThread = Thread.currentThread();
			ClassLoader threadContextClassLoader;
			try {
				threadContextClassLoader = currentThread.getContextClassLoader();
			}
			catch (Throwable ex) {
				// Cannot access thread context ClassLoader - falling back...
				return super.generate(cg);
			}
			// 设置当前线程的ContextClassLoader
			boolean overrideClassLoader = !this.classLoader.equals(threadContextClassLoader);
			if (overrideClassLoader) {
				currentThread.setContextClassLoader(this.classLoader);
			}
			try {
				return super.generate(cg);
			}
			finally {
				if (overrideClassLoader) {
					// Reset original thread context ClassLoader.
					currentThread.setContextClassLoader(threadContextClassLoader);
				}
			}
		}

上面generate 主要是封装一层,用于设置classLoader行为。因为 ClassLoaderAwareUndeclaredThrowableStrategy 构建时已传入ClassLoader,如果当前线程的classLoader和已有的不一致,就会用已有的classLoader替代当前线程的ClassLoader。
ClassLoaderAwareUndeclaredThrowableStrategy 继承结构图:
在这里插入图片描述
而目前 generate 将会进入DefaultGeneratorStrategy 中:

    public byte[] generate(ClassGenerator cg) throws Exception {
    // 获取一个 DebuggingClassWriter
        DebuggingClassWriter cw = this.getClassVisitor();
        // 调用 当前类的 transform 类的generatateClass
        this.transform(cg).generateClass(cw);
        return this.transform(cw.toByteArray());
    }
  • 获取一个 DebuggingClassWriter
  • 调用 transform 方法,实际当前类 ClassLoaderAwareUndeclaredThrowableStrategy 没有改方法,则去看它的父类,发现在 UndeclaredThrowableStrategy 有对父类的transform进行重写:
    protected ClassGenerator transform(ClassGenerator cg) throws Exception {
        ClassTransformer tr = new UndeclaredThrowableTransformer(this.wrapper);
        ClassTransformer tr = new MethodFilterTransformer(TRANSFORM_FILTER, tr);
        return new TransformingClassGenerator(cg, tr);
    }

所以最终调用到了 TransformingClassGeneratorgenerateClass 方法:

    public void generateClass(ClassVisitor v) throws Exception {
        this.t.setTarget(v);
        this.gen.generateClass(this.t);
    }
  • 此时设置ClassTransformer 的 target,target为 DebuggingClassWriter类型。
  • gen为Enhancer,就会进入generateClass方法,利用asm和cglib主要就在这里面
    最终,使用 ClassTransformer 封装,而由Enhancer具体调用获取类型信息
	public void generateClass(ClassVisitor v) throws Exception {
		// 获取父类
		Class sc = (superclass == null) ? Object.class : superclass;
		// final 类型不能进行代理
		if (TypeUtils.isFinal(sc.getModifiers()))
			throw new IllegalArgumentException("Cannot subclass final class " + sc.getName());
		// 获取构造方法
		List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors()));
		// 过滤一层,只保留可见的构造方法
		filterConstructors(sc, constructors);

		// Order is very important: must add superclass, then
		// its superclass chain, then each interface and
		// its superinterfaces.
		List actualMethods = new ArrayList();
		List interfaceMethods = new ArrayList();
		final Set forcePublic = new HashSet();
		// 将interface中所有方法,获取、处理后,全部放到actualMethods 、interfaceMethods 、forcePublic  中
		getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);
		// 将 actualMethods 中方法,经过层转化? 
		List methods = CollectionUtils.transform(actualMethods, new Transformer() {
			public Object transform(Object value) {
				Method method = (Method) value;
				int modifiers = Constants.ACC_FINAL
						| (method.getModifiers()
						& ~Constants.ACC_ABSTRACT
						& ~Constants.ACC_NATIVE
						& ~Constants.ACC_SYNCHRONIZED);
				if (forcePublic.contains(MethodWrapper.create(method))) {
					modifiers = (modifiers & ~Constants.ACC_PROTECTED) | Constants.ACC_PUBLIC;
				}
				return ReflectUtils.getMethodInfo(method, modifiers);
			}
		});
		// 声明cglib 类构造器
		ClassEmitter e = new ClassEmitter(v);
		if (currentData == null) {
			e.begin_class(Constants.V1_2,   // 版本
					Constants.ACC_PUBLIC,  // 访问性
					getClassName(),   // 类名
					Type.getType(sc), // 父类名
					(useFactory ?
							TypeUtils.add(TypeUtils.getTypes(interfaces), FACTORY) :
							TypeUtils.getTypes(interfaces)),   // 接口
					Constants.SOURCE_FILE);   // 类文件地址
		}
		else {
			e.begin_class(Constants.V1_2,
					Constants.ACC_PUBLIC,
					getClassName(),
					null,
					new Type[]{FACTORY},
					Constants.SOURCE_FILE);
		}
		List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance());
		// 声明字段
		e.declare_field(Constants.ACC_PRIVATE, BOUND_FIELD, Type.BOOLEAN_TYPE, null);
		e.declare_field(Constants.ACC_PUBLIC | Constants.ACC_STATIC, FACTORY_DATA_FIELD, OBJECT_TYPE, null);
		if (!interceptDuringConstruction) {
			e.declare_field(Constants.ACC_PRIVATE, CONSTRUCTED_FIELD, Type.BOOLEAN_TYPE, null);
		}
		e.declare_field(Constants.PRIVATE_FINAL_STATIC, THREAD_CALLBACKS_FIELD, THREAD_LOCAL, null);
		e.declare_field(Constants.PRIVATE_FINAL_STATIC, STATIC_CALLBACKS_FIELD, CALLBACK_ARRAY, null);
		if (serialVersionUID != null) {
			e.declare_field(Constants.PRIVATE_FINAL_STATIC, Constants.SUID_FIELD_NAME, Type.LONG_TYPE, serialVersionUID);
		}
		// 有多少callback,就声明多少字段
		for (int i = 0; i < callbackTypes.length; i++) {
			e.declare_field(Constants.ACC_PRIVATE, getCallbackField(i), callbackTypes[i], null);
		}
		// This is declared private to avoid "public field" pollution
		e.declare_field(Constants.ACC_PRIVATE | Constants.ACC_STATIC, CALLBACK_FILTER_FIELD, OBJECT_TYPE, null);

		if (currentData == null) {
		// 如果从未构造过,则使用actualMethods分别构造 方法和构造器
			emitMethods(e, methods, actualMethods);
			// 构造构造方法
			emitConstructors(e, constructorInfo);
		}
		else {
			emitDefaultConstructor(e);
		}
		// 构造threadCallback方法
		emitSetThreadCallbacks(e);
		// 构造 STATIC_CALLBACKS_FIELD 方法
		emitSetStaticCallbacks(e);
		// 构造 BIND_CALLBACKS
		emitBindCallbacks(e);
		// 构造其他callback
		if (useFactory || currentData != null) {
			int[] keys = getCallbackKeys();
			emitNewInstanceCallbacks(e);
			emitNewInstanceCallback(e);
			emitNewInstanceMultiarg(e, constructorInfo);
			emitGetCallback(e, keys);
			emitSetCallback(e, keys);
			emitGetCallbacks(e);
			emitSetCallbacks(e);
		}

		e.end_class();
	}

Enhancer 中generateClass 方法主要是构造类的框架,例如声明类,可见性设置,参数,再就是对每个方法进行判断拦截处理:

		if (currentData == null) {
			emitMethods(e, methods, actualMethods);
			emitConstructors(e, constructorInfo);
		}

而后,在emitMethods 方法中,则会对每个方法进行过滤并判断.

	private void emitMethods(final ClassEmitter ce, List methods, List actualMethods) {
		CallbackGenerator[] generators = CallbackInfo.getGenerators(callbackTypes);
		// 声明变量
		Map groups = new HashMap();
		final Map indexes = new HashMap();
		final Map originalModifiers = new HashMap();
		final Map positions = CollectionUtils.getIndexMap(methods);
		final Map declToBridge = new HashMap();

		Iterator it1 = methods.iterator();
		Iterator it2 = (actualMethods != null) ? actualMethods.iterator() : null;
		// 遍历所有methods
		while (it1.hasNext()) {
			MethodInfo method = (MethodInfo) it1.next();
			Method actualMethod = (it2 != null) ? (Method) it2.next() : null;
			// 判断方法类型,此时filter就是 开始传入的 ProxyCallbackFilter
			int index = filter.accept(actualMethod);
			if (index >= callbackTypes.length) {
				throw new IllegalArgumentException("Callback filter returned an index that is too large: " + index);
			}
			// 将方法和对应方法类型暂存起来
			originalModifiers.put(method, (actualMethod != null ? actualMethod.getModifiers() : method.getModifiers()));
			// 将方法和对应索引类型存起来
			indexes.put(method, index);
			List group = (List) groups.get(generators[index]);
			if (group == null) {
				// 存一份gerators和list,即将所有方法分类,存对应类型的多种方法
				groups.put(generators[index], group = new ArrayList(methods.size()));
			}
			group.add(method);

			// Optimization: build up a map of Class -> bridge methods in class
			// so that we can look up all the bridge methods in one pass for a class.
			if (TypeUtils.isBridge(actualMethod.getModifiers())) {
				// 对编译器自动生成的桥接方法处理
				Set bridges = (Set) declToBridge.get(actualMethod.getDeclaringClass());
				if (bridges == null) {
					bridges = new HashSet();
					declToBridge.put(actualMethod.getDeclaringClass(), bridges);
				}
				bridges.add(method.getSignature());
			}
		}
	final Map bridgeToTarget = new BridgeMethodResolver(declToBridge, getClassLoader()).resolveAll();

		Set seenGen = new HashSet();
		// 存threadLocal?
		CodeEmitter se = ce.getStaticHook();
		se.new_instance(THREAD_LOCAL);
		se.dup();
		se.invoke_constructor(THREAD_LOCAL, CSTRUCT_NULL);
		se.putfield(THREAD_CALLBACKS_FIELD);

		final Object[] state = new Object[1];
		// 构造一份自己的 CallbackGenerator.Context
		CallbackGenerator.Context context = new CallbackGenerator.Context() {
			public ClassLoader getClassLoader() {
				return Enhancer.this.getClassLoader();
			}

			public int getOriginalModifiers(MethodInfo method) {
				return ((Integer) originalModifiers.get(method)).intValue();
			}

			public int getIndex(MethodInfo method) {
				return ((Integer) indexes.get(method)).intValue();
			}

			public void emitCallback(CodeEmitter e, int index) {
				emitCurrentCallback(e, index);
			}

			public Signature getImplSignature(MethodInfo method) {
				return rename(method.getSignature(), ((Integer) positions.get(method)).intValue());
			}

			public void emitLoadArgsAndInvoke(CodeEmitter e, MethodInfo method) {
				// If this is a bridge and we know the target was called from invokespecial,
				// then we need to invoke_virtual w/ the bridge target instead of doing
				// a super, because super may itself be using super, which would bypass
				// any proxies on the target.
				Signature bridgeTarget = (Signature) bridgeToTarget.get(method.getSignature());
				if (bridgeTarget != null) {
					// checkcast each argument against the target's argument types
					for (int i = 0; i < bridgeTarget.getArgumentTypes().length; i++) {
						e.load_arg(i);
						Type target = bridgeTarget.getArgumentTypes()[i];
						if (!target.equals(method.getSignature().getArgumentTypes()[i])) {
							e.checkcast(target);
						}
					}

					e.invoke_virtual_this(bridgeTarget);

					Type retType = method.getSignature().getReturnType();
					// Not necessary to cast if the target & bridge have
					// the same return type.
					// (This conveniently includes void and primitive types,
					// which would fail if casted.  It's not possible to
					// covariant from boxed to unbox (or vice versa), so no having
					// to box/unbox for bridges).
					// TODO: It also isn't necessary to checkcast if the return is
					// assignable from the target.  (This would happen if a subclass
					// used covariant returns to narrow the return type within a bridge
					// method.)
					if (!retType.equals(bridgeTarget.getReturnType())) {
						e.checkcast(retType);
					}
				}
				else {
					e.load_args();
					e.super_invoke(method.getSignature());
				}
			}

			public CodeEmitter beginMethod(ClassEmitter ce, MethodInfo method) {
				CodeEmitter e = EmitUtils.begin_method(ce, method);
				if (!interceptDuringConstruction &&
						!TypeUtils.isAbstract(method.getModifiers())) {
					Label constructed = e.make_label();
					e.load_this();
					e.getfield(CONSTRUCTED_FIELD);
					e.if_jump(CodeEmitter.NE, constructed);
					e.load_this();
					e.load_args();
					e.super_invoke();
					e.return_value();
					e.mark(constructed);
				}
				return e;
			}
		};
		// 对对应callbackTypes遍历并生成方法
		for (int i = 0; i < callbackTypes.length; i++) {
			CallbackGenerator gen = generators[i];
			if (!seenGen.contains(gen)) {
				seenGen.add(gen);
				// 获取该类型的所有方法
				final List fmethods = (List) groups.get(gen);
				if (fmethods != null) {
					try {
						// 调用对应CallbackGenerator 生成方法
						gen.generate(ce, context, fmethods);
						gen.generateStatic(se, context, fmethods);
					}
					catch (RuntimeException x) {
						throw x;
					}
					catch (Exception x) {
						throw new CodeGenerationException(x);
					}
				}
			}
		}
		// 设置返回值
		se.return_value();
		se.end_method();
  • 声明变量
  • 遍历所有,将方法对应类型匹配出来,这个类型就是上面callbackTypes。
  • 将第二步中匹配的信息暂存起来
  • 构造 CallbackGenerator.Context ,工创建方法使用
  • 遍历 callbackTypes ,调用它们的generate方法进行方法构建。
    这里的CallbackType 就是开始传入的多种CallbackGenrator:
    在这里插入图片描述

ProxyCallbackFilter

整个生成方法流程已大致走完,获取aop方法时,有通过 ProxyCallbackFilter 对方法类型进行判断:
int index = filter.accept(actualMethod);
进而看

		public int accept(Method method) {
			if (AopUtils.isFinalizeMethod(method)) {
				logger.trace("Found finalize() method - using NO_OVERRIDE");
				return NO_OVERRIDE;
			}
			if (!this.advised.isOpaque() && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
				if (logger.isTraceEnabled()) {
					logger.trace("Method is declared on Advised interface: " + method);
				}
				return DISPATCH_ADVISED;
			}
			// We must always proxy equals, to direct calls to this.
			if (AopUtils.isEqualsMethod(method)) {
				if (logger.isTraceEnabled()) {
					logger.trace("Found 'equals' method: " + method);
				}
				return INVOKE_EQUALS;
			}
			// We must always calculate hashCode based on the proxy.
			if (AopUtils.isHashCodeMethod(method)) {
				if (logger.isTraceEnabled()) {
					logger.trace("Found 'hashCode' method: " + method);
				}
				return INVOKE_HASHCODE;
			}
			Class<?> targetClass = this.advised.getTargetClass();
			// Proxy is not yet available, but that shouldn't matter.
			List<?> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
			boolean haveAdvice = !chain.isEmpty();
			boolean exposeProxy = this.advised.isExposeProxy();
			boolean isStatic = this.advised.getTargetSource().isStatic();
			boolean isFrozen = this.advised.isFrozen();
			if (haveAdvice || !isFrozen) {
				// If exposing the proxy, then AOP_PROXY must be used.
				if (exposeProxy) {
					if (logger.isTraceEnabled()) {
						logger.trace("Must expose proxy on advised method: " + method);
					}
					return AOP_PROXY;
				}
				String key = method.toString();
				// Check to see if we have fixed interceptor to serve this method.
				// Else use the AOP_PROXY.
				if (isStatic && isFrozen && this.fixedInterceptorMap.containsKey(key)) {
					if (logger.isTraceEnabled()) {
						logger.trace("Method has advice and optimizations are enabled: " + method);
					}
					// We know that we are optimizing so we can use the FixedStaticChainInterceptors.
					int index = this.fixedInterceptorMap.get(key);
					return (index + this.fixedInterceptorOffset);
				}
				else {
					if (logger.isTraceEnabled()) {
						logger.trace("Unable to apply any optimizations to advised method: " + method);
					}
					return AOP_PROXY;
				}
			}
			else {
				// See if the return type of the method is outside the class hierarchy of the target type.
				// If so we know it never needs to have return type massage and can use a dispatcher.
				// If the proxy is being exposed, then must use the interceptor the correct one is already
				// configured. If the target is not static, then we cannot use a dispatcher because the
				// target needs to be explicitly released after the invocation.
				if (exposeProxy || !isStatic) {
					return INVOKE_TARGET;
				}
				Class<?> returnType = method.getReturnType();
				if (targetClass != null && returnType.isAssignableFrom(targetClass)) {
					if (logger.isTraceEnabled()) {
						logger.trace("Method return type is assignable from target type and " +
								"may therefore return 'this' - using INVOKE_TARGET: " + method);
					}
					return INVOKE_TARGET;
				}
				else {
					if (logger.isTraceEnabled()) {
						logger.trace("Method return type ensures 'this' cannot be returned - " +
								"using DISPATCH_TARGET: " + method);
					}
					return DISPATCH_TARGET;
				}
			}
		}

本方法主要判断方法类型,而对于是否有切面方法,则是通过AdvisedSupportgetInterceptorsAndDynamicInterceptionAdvice,原理就是对每个命中的advisor进行遍历判断,如果符合则有切面:

	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
		MethodCacheKey cacheKey = new MethodCacheKey(method);
		// 优先取缓存
		List<Object> cached = this.methodCache.get(cacheKey);
		if (cached == null) {
		// 委托给AdvisorChainFactory 搜寻
			cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
					this, method, targetClass);
			this.methodCache.put(cacheKey, cached);
		}
		return cached;
	}

而再看 AdvisorChainFactorygetInterceptorsAndDynamicInterceptionAdvice方法:

	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
			Advised config, Method method, @Nullable Class<?> targetClass) {

		// This is somewhat tricky... We have to process introductions first,
		// but we need to preserve order in the ultimate list.
		AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
		Advisor[] advisors = config.getAdvisors();
		List<Object> interceptorList = new ArrayList<>(advisors.length);
		Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
		Boolean hasIntroductions = null;
		// 遍历所有advisor
		for (Advisor advisor : advisors) {
			if (advisor instanceof PointcutAdvisor) {
				// Add it conditionally.
				PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
				if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
					MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
					boolean match;
					if (mm instanceof IntroductionAwareMethodMatcher) {
						if (hasIntroductions == null) {
							hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
						}
						match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
					}
					else {
						match = mm.matches(method, actualClass);
					}
					if (match) {
						MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
						if (mm.isRuntime()) {
							// Creating a new object instance in the getInterceptors() method
							// isn't a problem as we normally cache created chains.
							for (MethodInterceptor interceptor : interceptors) {
								interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
							}
						}
						else {
							interceptorList.addAll(Arrays.asList(interceptors));
						}
					}
				}
			}
			else if (advisor instanceof IntroductionAdvisor) {
				IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
				if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
					Interceptor[] interceptors = registry.getInterceptors(advisor);
					interceptorList.addAll(Arrays.asList(interceptors));
				}
			}
			else {
				Interceptor[] interceptors = registry.getInterceptors(advisor);
				interceptorList.addAll(Arrays.asList(interceptors));
			}
		}

		return interceptorList;
	}

总结

当创建代理后,如果有aop类型,则会先进入DynamicAdvisedInterceptor 的intercept方法中,具体可以看博主上篇文章。
整个Spring 使用 CGLIB 创建代理走下来,其实,博主也没完全懂,估计就懂个20%吧。但是感觉博主跟Spring Aop CGLIB是朋友了,熟悉了,已有想扩展,或者排查问题,再进来看代码,也认识呀。

觉得博主写的有用,不妨关注博主公众号: 六点A君。
哈哈哈,一起研究Spring:
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOP使用CGLIB作为默认的代理方式来实现动态代理代理过程中,首先需要定义一个被代理的目标对象或者叫做目标类。该目标对象可以是任何一个Java对象,它会在运行时被代理创建。然后,通过Spring的配置文件或者注解,将该目标对象注入到Spring容器中。 接下来,需要定义一个切面类,该类中包含了代理的具体操作和条件。这些操作和条件可以是在目标对象的方法执行前后增加日志、事务控制、权限验证等。切面类通常会实现Advice接口或者继承AbstractAspectJAdvice类。 在Spring容器启动时,会根据配置文件或者注解自动扫描到切面类,并且生成代理对象。生成代理对象的方式有两种:JDK动态代理CGLIB动态代理。在Spring AOP中,默认使用CGLIB动态代理方式,因为CGLIB可以代理没有实现接口的目标类。 当目标对象的方法被调用时,代理对象会先调用切面类的相应方法,然后再调用目标对象的方法。这样,代理对象就可以在目标对象方法执行前后,添加自己的逻辑。 CGLIB是一个强大的第三方类库,它通过继承的方式创建代理对象。通过修改字节码,可以在目标类中创建子类,并将代理逻辑插入到子类的方法中,从而实现代理的功能。 总之,Spring AOP使用CGLIB作为默认的代理方式来实现动态代理代理过程中,首先需要定义目标对象和切面类,然后通过配置文件或者注解将它们注入到Spring容器中。在运行时,Spring容器会自动生成代理对象,并在方法执行前后执行切面逻辑,实现代理的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值