SpringAOP详解-源码解析

219 阅读25分钟

SpringAOP源码解析

AOP概述

概念解析

  • 连接点 JoinPoint

    • CardService类中的三个方法都可以被增强(增加一些功能,比如方法调用前后的日志打印),哪些方法可以被增强,那这些方法就可以被称为连接点,所以这三个方法(add,find,edit)都可以被称为连接点。
  • 切入点 PointCut

    • 假如我们只增强某个方法,那这些实际被我们增强的方法就称为切入点,真正增强的方法才成为切入点,没有实际增强(可以被增强但是没有增强)的不是。比如我们指定在add方法和edit方法前后打印日志,那么切入点就是add方法和edit方法

    • 对应AspectTest类中的pointCut方法上的**@Pointcut注解**

  • 通知 Advice

    • 假如我们要在add方法进行之后做一些其它操作,那我们在方法进行后添加的代码部分就称为增强(通知),也就是说实际增加的逻辑部分就称为通知。

    • 对应AspectTest类中的**@AfterReturning,@Around,@After,@Before,@AfterThrowing**五个注解修饰的方法

  • Advisor (通知器)

    • 作用:Advisor 是一个包含切入点(Pointcut)和增强(Advice)的组合,它告诉 AOP 框架在何时(切入点)以及如何(增强)干预目标对象的行为。

    • 组成:一个 Advisor 通常由两部分组成:

      • Pointcut(切入点):定义了在目标对象的哪些方法上应用增强。例如,可以使用表达式或注解来指定切入点。
      • Advice(增强):定义了在切入点何时执行的逻辑,例如在方法执行前后、抛出异常时等。
  • 切面 Aspect

    • 切面指的是一个动作或过程,指的就是把通知应用到切入点的过程,假如我们想对add方法加上增强,我们把增强的部分加上去的过程就叫切面。

    • 整个AspectTest的类被**@Aspect**注解修饰,说明这是一个切面

  • 目标对象

    • CardService类就是我们的目标对象
  • 代理对象

    • 将切面织入目标对象后所得到的就是代理对象。代理对象是具备通知所定义的功能和目标对象的业务功能。
  • 织入

    • 把切面应用到目标对象来创建新的代理对象的过程。切面的织入有三种方式

      • 编译时织入(Compile-Time Weaving)

        • 织入发生在源代码编译阶段。
        • 需要特殊的编译器或工具来进行AOP织入。
        • 修改源代码,因此需要访问源代码的权限。
        • 生成的目标类已经包含了切面的逻辑,无需在运行时再次织入。
      • 类加载时织入(Load-Time Weaving)

        • 织入发生在类加载过程中,但在类被实际加载到内存前。
        • 使用字节码增强工具(如AspectJ的LTW或Java Agent)来实现。
        • 不需要修改源代码,但需要特殊的配置和启动参数来启用织入。
        • 可以选择性地为某些类启用AOP织入,而不影响其他类。
      • 运行时织入(Run-Time Weaving)

        • 织入发生在应用程序运行时。
        • 通常使用代理对象来实现AOP,代理对象在运行时动态添加切面逻辑。
        • 不需要修改源代码或进行特殊的编译,更加灵活。
        • 允许动态地添加、修改或删除切面,因为织入是在运行时发生的。

springAOP通常使用运行时织入(Run-Time Weaving)方式来实现。

CGLIB实现流程

  1. 通过new Enhancer()方法创建Enhancer实例的时候。会提前加载Enhancer内部所有被static修饰的属性。其中有个关键属性private static final EnhancerKey KEY_FACTORY = (EnhancerKey) KeyFactory.create(EnhancerKey.class, KeyFactory.HASH_ASM_TYPE, null)。通过KeyFactory的create静态方法创建KeyFactroy的代理类用于后面生成代理类的唯一标识。
  2. Enhancer继承了AbstractClassGenerator,创建Enhancer时也会加载AbstractClassGenerator类,完成AbstractClassGenerator中static修饰的属性创建。(这里面都是一些缓存,用于提高aop性能)
  3. 设置完SuperClass和callback之后。通过 enhancer.create()方法就能创建目标对象的代理对象。
  4. 在create方法内部会调用createHelper()方法。
  5. 通过createHelper方法最终会进入Enhancer实现的generateClass方法,通过ASM字节码生成代理类并放入缓存。
  6. 然后通过Enhancer类的unwrapCachedValue方法将当前代理信息封装成一个EnhancerFactoryData对象并返回。
  7. 最终调用EnhancerFactoryData的newInstance方法返回代理对象实例

源码解析

Enhancer类

概述

Enhancer 类是 CGLib 中最常用的一个类,使用 Enhancer 类生成动态子类以启用方法拦截。

相关方法

  • // 我们创建完Enhancer后,设置完SuperClass和callback之后,通过调用create方法获取生成代理子类
    public Object create() {
        this.classOnly = false;
        this.argumentTypes = null;
        return this.createHelper();
    }
    
  • private Object createHelper() {
      	// 前置验证
        preValidate();
      	// 荣国KEY_FACTORY.newInstance方法生成key
        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方法开始创建代理子类,最终会调用到Enhancer的generateClass方法
        Object result = super.create(key);
        return result;
    }
    
  • // 该方法
    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()));
     		// 去掉private之类的不能被继承的构造函数
        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();
      	// 声明所有必须为public的方法集合  这儿主要是代理接口接口的方法
        final Set forcePublic = new HashSet();
      	// 即通过传入的代理类,代理接口,遍历所有的方法并放入对应的集合
        getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);
    		//  对所有代理类方法修饰符做处理
        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);
           }
        });
    
        ClassEmitter e = new ClassEmitter(v);
        if (currentData == null) {
           e.begin_class(Constants.V1_8,
                 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_8,
                 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);
        }
    
        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) {
           emitMethods(e, methods, actualMethods);
           emitConstructors(e, constructorInfo);
        }
        else {
           emitDefaultConstructor(e);
        }
        emitSetThreadCallbacks(e);
        emitSetStaticCallbacks(e);
        emitBindCallbacks(e);
    
        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();
    }
    
  • 	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) {
    						Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
    						data = new ClassLoaderData(loader);
    						newCache.put(loader, data);
    						CACHE = newCache;
    					}
    				}
    			}
    			this.key = key;
          // 获取代理类,这里被封装为了EnhancerFactoryData类型,里面保存了代理类的ClassLoader,回调方法,主构造函数信息等。
    			Object obj = data.get(this, getUseCache());
    			if (obj instanceof Class) {
    				return firstInstance((Class) obj);
    			}
          // 这里最终会调用EnhancerFactoryData的newInstance方法,通过反射创建代理对象实例
    			return nextInstance(obj);
    		}
    		catch (RuntimeException | Error ex) {
    			throw ex;
    		}
    		catch (Exception ex) {
    			throw new CodeGenerationException(ex);
    		}
    	}
    

EnhancerFactoryData类

	static class EnhancerFactoryData {
		// 代理类的Class信息
		public final Class generatedClass;
		// 回调函数信息
		private final Method setThreadCallbacks;
		// 主构造函数参数列表
		private final Class[] primaryConstructorArgTypes;
		// 主构造函数
		private final Constructor primaryConstructor;

		public EnhancerFactoryData(Class generatedClass, Class[] primaryConstructorArgTypes, boolean classOnly) {
			this.generatedClass = generatedClass;
			try {
        // 获取所有的回调,实际上就是我们自定义的实现了MethodInterceptor接口的切面
				setThreadCallbacks = getCallbacksSetter(generatedClass, SET_THREAD_CALLBACKS_NAME);
				if (classOnly) {
					this.primaryConstructorArgTypes = null;
					this.primaryConstructor = null;
				}
				else {
					this.primaryConstructorArgTypes = primaryConstructorArgTypes;
					this.primaryConstructor = ReflectUtils.getConstructor(generatedClass, primaryConstructorArgTypes);
				}
			}
			catch (NoSuchMethodException e) {
				throw new CodeGenerationException(e);
			}
		}

		// 为给定的参数类型创建代理实例,并分配回调。理想情况下,对于每个代理类,只应使用一组参数类型,否则将不得不在构造函数查找上花费时间
		public Object newInstance(Class[] argumentTypes, Object[] arguments, Callback[] callbacks) {
			setThreadCallbacks(callbacks);
			try {
				// Explicit reference equality is added here just in case Arrays.equals does not have one
				if (primaryConstructorArgTypes == argumentTypes ||
						Arrays.equals(primaryConstructorArgTypes, argumentTypes)) {
					// If we have relevant Constructor instance at hand, just call it
					// This skips "get constructors" machinery
					return ReflectUtils.newInstance(primaryConstructor, arguments);
				}
				// Take a slow path if observing unexpected argument types
        // 通过反射创建代理类实例并返回
				return ReflectUtils.newInstance(generatedClass, argumentTypes, arguments);
			}
			finally {
				// clear thread callbacks to allow them to be gc'd
				setThreadCallbacks(null);
			}

		}

		private void setThreadCallbacks(Callback[] callbacks) {
			try {
				setThreadCallbacks.invoke(generatedClass, (Object) callbacks);
			}
			catch (IllegalAccessException e) {
				throw new CodeGenerationException(e);
			}
			catch (InvocationTargetException e) {
				throw new CodeGenerationException(e.getTargetException());
			}
		}
	}

KeyFactory类

通过KeyFactory的create静态方法创建KeyFactroy的代理。用于后面生成代理对象唯一标识,通过唯一标识来在运行时查找和缓存代理类的实例。提高aop性能。

AbstractClassGenerator类

  • 核心功能

通过asm方式生成代理类的class文件。

实现ClassGenerator接口,但没有实现接口中的generateClass方法,

  • 缓存

    • 在运行时,一个类或者接口并不是单单由它的名称确x的,而是由它的二进制名称以及它的定义类加载器共同确定的。每个这样的类或者接口都属于一个运行时包,运行时包则由包名和定义类加载器共同确定。上述中所谓的定义类加载器实际上就是getClassLoader()的返回值,而这个概念的产生则跟类加载过程中的“双亲委派机制”有关。当要加载一个类时,第一个发起类加载的加载器称之为“初始类加载器”(initiating loader),但是根据“双亲委派机制”,它会先将加载委派给父加载器,如果父加载器加载失败,才会最终由自己尝试加载。而无论哪个加载器加载成功,它就是该类的定义类加载器(defining class loader)。
  • ClassLoaderData静态内部类

    保存ClassLoader的数据

    	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);
    						}
    					};
    			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) {
            // 不适用缓存直接调用方法获取当前ClassLoader加载的类信息
    				return gen.generate(ClassLoaderData.this);
    			}
    			else {
            //直接generatedClasses中我们每次新加ClassLoaderData对象时创建的load回调函数最终调用到AbstractClassGenerator的generate获取当前ClassLoader加载的类信息
    				Object cachedValue = generatedClasses.get(gen);
    				return gen.unwrapCachedValue(cachedValue);
    			}
    		}
    	}
    

Generator(AbstractClassGenerator的实现类)

  • 实现了ClassGenerator的generateClass方法。主要就是保存了当前类的ClassLoader信息和类信息以及当前的类权限保护域信息。

  • 在java中,以类为单位,将不同的类分在不同的保护域。每个类加载器具有一个保护域,使用同一个类加载器加载的类在同一个保护域,也就是说具有相同的权限。java可以对不同的保护区授予不同的权限,那么这块区域中的代码(类)就会拥有所在保护区的权限。

  • 在KeyFactory类内部,是一个内部类

  • 实现了generateClass方法

  • 		public void generateClass(ClassVisitor v) {
      			/**
      			 * 在CGLIB中,CodeEmitter类是一个核心组件,它负责生成字节码并定义类的行为。它可以理解为一个代码发射器,用于将特定的指令序列生成为目标类的字节码。
      			 * 通过使用CodeEmitter,我们可以动态地创建新的类,或者在现有类的基础上进行扩展。
      			 * CodeEmitter的作用可以总结如下:
      			 * 	生成字节码:CodeEmitter负责将Java代码转化为字节码指令序列,这样可以在运行时动态地创建新的类或者修改现有类的行为。
      			 * 	实现动态代理:在Spring中,CGLIB通常被用于创建动态代理对象。CodeEmitter负责生成代理类的字节码,使得代理对象能够拦截目标方法的调用并执行额外的逻辑。
      			 * 	实现AOP:在AOP中,我们可以通过在目标方法的前后插入一些代码来实现对方法的增强。CodeEmitter可以用来生成拦截器,使得我们能够在目标方法执行前后添加额外的逻辑。
      			 */
      			ClassEmitter ce = new ClassEmitter(v);
      			//找到被代理类的newInstance方法。如果没有会报异常,由此可知,如果想用Generator代理类生成器,必须要有newInstance方法
      			Method newInstance = ReflectUtils.findNewInstance(keyInterface);
      			//如果被代理类的newInstance不为Object则报异常,此处我们代理的Enchaer.EnhancerKey newInstance方法返回值为Object
      			if (!newInstance.getReturnType().equals(Object.class)) {
      				throw new IllegalArgumentException("newInstance method must return Object");
      			}
      			//获取被代理类的newInstance方法的参数类型
      			Type[] parameterTypes = TypeUtils.getTypes(newInstance.getParameterTypes());
      			// 1.创建类,写入类头,版本号,访问权限,类名等通用信息
      			ce.begin_class(Constants.V1_8,
      					Constants.ACC_PUBLIC,
      					getClassName(),
      					KEY_FACTORY,
      					new Type[]{Type.getType(keyInterface)},
      					Constants.SOURCE_FILE);
      			// 2.创建默认无参构造函数
      			EmitUtils.null_constructor(ce);
      			// 3.写入newInstance方法
      			EmitUtils.factory_method(ce, ReflectUtils.getSignature(newInstance));
      
      			int seed = 0;
      			/**
      			 *
      			 * CodeEmitter类是CGLIB(Code Generation Library)库中的一个核心组件。它负责生成字节码并定义类的行为,允许在运行时动态地创建新的类或者修改现有类的行为。
      			 * 具体来说,CodeEmitter类主要提供了以下功能:
      			 * 	生成字节码指令序列: CodeEmitter可以将高级的Java代码转换为底层的字节码指令序列。这使得我们能够在运行时动态地生成新的类,或者在现有类的基础上进行扩展。
      			 * 	实现动态代理: 在Spring框架中,CGLIB通常用于创建动态代理对象。CodeEmitter负责生成代理类的字节码,使得代理对象能够拦截目标方法的调用并执行额外的逻辑。
      			 * 	实现AOP(面向切面编程): 在AOP中,我们可以通过在目标方法的前后插入一些代码来实现对方法的增强。CodeEmitter可以用来生成拦截器,使得我们能够在目标方法执行前后添加额外的逻辑。
      			 */
      			// 4.开始构造有参构造方法
      			CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC,
      					TypeUtils.parseConstructor(parameterTypes),
      					null);
      			e.load_this();
      			// 开始调用父类的构造方法
      			e.super_invoke_constructor();
      			e.load_this();
      			// 找到传入的Customizer
      			List<FieldTypeCustomizer> fieldTypeCustomizers = getCustomizers(FieldTypeCustomizer.class);
      			// 遍历即newInstance方法的所有参数
      			for (int i = 0; i < parameterTypes.length; i++) {
      				Type parameterType = parameterTypes[i];
      				// 获取参数的类型
      				Type fieldType = parameterType;
      				// 如果有Customizer,则对参数进行定制
      				for (FieldTypeCustomizer customizer : fieldTypeCustomizers) {
      					fieldType = customizer.getOutType(i, fieldType);
      				}
      				seed += fieldType.hashCode();
      				// 为每个参数创建一个字段
      				ce.declare_field(Constants.ACC_PRIVATE | Constants.ACC_FINAL,
      						getFieldName(i),
      						fieldType,
      						null);
      				e.dup();
      				e.load_arg(i);
      				// 如果有Customizer,则对参数进行定制
      				for (FieldTypeCustomizer customizer : fieldTypeCustomizers) {
      					customizer.customize(e, i, parameterType);
      				}
      				e.putfield(getFieldName(i));
      			}
      			// 设置方法返回值
      			e.return_value();
      			// 结束构造方法
      			e.end_method();
      
      			// hash code 开始写入hashCode方法
      			e = ce.begin_method(Constants.ACC_PUBLIC, HASH_CODE, null);
      			int hc = (constant != 0) ? constant : PRIMES[(Math.abs(seed) % PRIMES.length)];
      			int hm = (multiplier != 0) ? multiplier : PRIMES[(Math.abs(seed * 13) % PRIMES.length)];
      			e.push(hc);
      			for (int i = 0; i < parameterTypes.length; i++) {
      				e.load_this();
      				e.getfield(getFieldName(i));
      				EmitUtils.hash_code(e, parameterTypes[i], hm, customizers);
      			}
      			e.return_value();
      			e.end_method();
      
      			// equals  开始写入equals方法
      			e = ce.begin_method(Constants.ACC_PUBLIC, EQUALS, null);
      			Label fail = e.make_label();
      			e.load_arg(0);
      			e.instance_of_this();
      			e.if_jump(CodeEmitter.EQ, fail);
      			for (int i = 0; i < parameterTypes.length; i++) {
      				e.load_this();
      				e.getfield(getFieldName(i));
      				e.load_arg(0);
      				e.checkcast_this();
      				e.getfield(getFieldName(i));
      				EmitUtils.not_equals(e, parameterTypes[i], fail, customizers);
      			}
      			e.push(1);
      			e.return_value();
      			e.mark(fail);
      			e.push(0);
      			e.return_value();
      			e.end_method();
      
      			// toString  开始写入toString方法
      			e = ce.begin_method(Constants.ACC_PUBLIC, TO_STRING, null);
      			e.new_instance(Constants.TYPE_STRING_BUFFER);
      			e.dup();
      			e.invoke_constructor(Constants.TYPE_STRING_BUFFER);
      			for (int i = 0; i < parameterTypes.length; i++) {
      				if (i > 0) {
      					e.push(", ");
      					e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_STRING);
      				}
      				e.load_this();
      				e.getfield(getFieldName(i));
      				EmitUtils.append_string(e, parameterTypes[i], EmitUtils.DEFAULT_DELIMITERS, customizers);
      			}
      			e.invoke_virtual(Constants.TYPE_STRING_BUFFER, TO_STRING);
      			e.return_value();
      			e.end_method();
      			// 类写入结束,至此类信息收集完成并全部写入ClassVisitor
      			ce.end_class();
      		}
    

DefaultNamingPolicy类

默认的类名生成策略。通过getClassName方法生成代理类的类名

public String getClassName(String prefix, String source, Object key, Predicate names) {
  	// 如果没有类的前缀名,生成默认前缀名
    if (prefix == null) {
        prefix = "org.springframework.cglib.empty.Object";
    } else if (prefix.startsWith("java")) {
        prefix = "$" + prefix;
    }

    String base = prefix + "$$" + source.substring(source.lastIndexOf(46) + 1) + this.getTag() + "$$" + Integer.toHexString(STRESS_HASH_CODE ? 0 : key.hashCode());
    String attempt = base;

    for(int index = 2; names.evaluate(attempt); attempt = base + "_" + index++) {
    }

    return attempt;
}

DefaultGeneratorStrategy类

默认的字节码处理来。通过该类以ASM字节码完成对类的字节码二进制流生成

// 这是通过ASM的方式生成代理类的入口
public byte[] generate(ClassGenerator cg) throws Exception {
  DebuggingClassWriter cw = this.getClassVisitor();
  // 此处通过完成类的字节码生成写入cw
  this.transform(cg).generateClass(cw);
  // cw生成对应的二进制流
  return this.transform(cw.toByteArray());
}

SpringAOP详解

代码示例

业务代码

public class CardService {

	public void add() {
		System.out.println("add");
	}
	public void find() {
		System.out.println("find");
	}
	
	public void edit() {
		System.out.println("edit");
	}
}

切面类代码

@Aspect
@Component
public class AspectTest {

	@Before("pointcut()")
	public void before() {
		System.out.println("before");
	}

	@After("pointcut()")
	public void after() {
		System.out.println("after");
	}

	@Around("pointcut()")
	public void around() {
		System.out.println("around");
	}

	@AfterReturning("pointcut()")
	public void afterReturning() {
		System.out.println("afterReturning");
	}
  
  @AfterThrowing("pointcut()")
	public void afterThrowing() {
		System.out.println("afterThrowing");
	}

	@Pointcut("execution(* circulate.*.test(..))")
	public void pointcut() {
	}
}

切面解析流程

  1. AbstractAutowireCapableBeanFactory的createBean方法

  2. AbstractAutowireCapableBeanFactory的resolveBeforeInstantiation方法(这里会调用所有的InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation 这是入口一)

    1. 	@Nullable
      	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
      		Object bean = null;
      		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
      			// Make sure bean class is actually resolved at this point.
      			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      				Class<?> targetType = determineTargetType(beanName, mbd);
      				if (targetType != null) {
                // 这里会调用所有的InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法。aop代理类AbstractAutoProxyCreator就实现了InstantiationAwareBeanPostProcessor接口并重写了postProcessBeforeInstantiation方法。
      					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
      					if (bean != null) {
      						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
      					}
      				}
      			}
      			mbd.beforeInstantiationResolved = (bean != null);
      		}
      		return bean;
      	}
      
      
  3. AbstractAutoProxyCreator的postProcessBeforeInstantiation方法

    1. 	@Override
      	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
      		// 获取当前bean的cacheKey
      		Object cacheKey = getCacheKey(beanClass, beanName);
      		// 如果当前beanName为空或者当前bean不在targetSourcedBeans中
      		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
      			// 如果当前bean的cacheKey在advisedBeans中存在,则直接返回null
      			if (this.advisedBeans.containsKey(cacheKey)) {
      				return null;
      			}
      			//判断当前beanClass是否为aop基础类(Advice, Pointcut, Advisor, AopInfrastructureBean),如果是基础类直接保存到advisedBeans中并返回null
      			//判断当前bean是否要跳过,如果要跳过直接保存到advisedBeans中并返回null
      			// advisedBeans是一个缓存,所有处理过的bean都会被缓存起来,下次再次处理时,如果发现缓存中已经存在,则直接返回null
      			// 调用AspectJAwareAdvisorAutoProxyCreator的shouldSkip方法。这个方法内部会调用到AnnotationAwareAspectJAutoProxyCreator的findCandidateAdvisors方法。
      			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
      				this.advisedBeans.put(cacheKey, Boolean.FALSE);
      				return null;
      			}
      		}
      
      		// Create proxy here if we have a custom TargetSource.
      		// Suppresses unnecessary default instantiation of the target bean:
      		// The TargetSource will handle target instances in a custom fashion.
      		// 此处在resolveBeforeInstantiation方法(创建bean实例之前会被调用)
      		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
      		if (targetSource != null) {
      			if (StringUtils.hasLength(beanName)) {
      				this.targetSourcedBeans.add(beanName);
      			}
            // 通过给定的beanClass获取当前当前bean能够使用的所有Advisor和Advices
      			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            // 创建给定beanClass的带来对象
      			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
            // 放入缓存
      			this.proxyTypes.put(cacheKey, proxy.getClass());
      			return proxy;
      		}
      
      		return null;
      	}
      
  4. AnnotationAwareAspectJAutoProxyCreator的findCandidateAdvisors方法,获取所有的Advisor

    1. 	@Override
      	protected List<Advisor> findCandidateAdvisors() {
      		// AbstractAdvisorAutoProxyCreator的findCandidateAdvisors方法,从容器中获取所有的Advisor,这里获取加载了配置文件中的Advisor
      		List<Advisor> advisors = super.findCandidateAdvisors();
      		// Build Advisors for all AspectJ aspects in the bean factory.
      		if (this.aspectJAdvisorsBuilder != null) {
            // 通过aspectJAdvisorsBuilder获取spring容器中通过注解定义的Advisor。实际调用BeanFactoryAspectJAdvisorsBuilder的buildAspectJAdvisors方法
      			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
      		}
      		return advisors;
      	}
      
  5. BeanFactoryAspectJAdvisorsBuilder的buildAspectJAdvisors方法开始处理所有@Aspectj注解修饰的类

    1. 	public List<Advisor> buildAspectJAdvisors() {
      		// 所有被@Aspect注解的类的beanName
      		List<String> aspectNames = this.aspectBeanNames;
      
      		if (aspectNames == null) {
      			synchronized (this) {
      				aspectNames = this.aspectBeanNames;
      				if (aspectNames == null) {
      					List<Advisor> advisors = new ArrayList<>();
      					// 用于保存所有的@Aspect注解的类的beanName
      					aspectNames = new ArrayList<>();
      					// 获取所有的beanName
      					String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
      							this.beanFactory, Object.class, true, false);
      					for (String beanName : beanNames) {
      						if (!isEligibleBean(beanName)) {
      							continue;
      						}
      						// We must be careful not to instantiate beans eagerly as in this case they
      						// would be cached by the Spring container but would not have been weaved.
      						// 所有被@Aspect注解的类的beanName
      						Class<?> beanType = this.beanFactory.getType(beanName, false);
      						if (beanType == null) {
      							continue;
      						}
      						// 判断是否是@Aspect注解的类
      						if (this.advisorFactory.isAspect(beanType)) {
      							// 将当前beanName添加到aspectNames中
      							aspectNames.add(beanName);
      							// 根据当前beanName和beanType创建AspectMetadata对象,完成对@Aspect注解的解析
      							AspectMetadata amd = new AspectMetadata(beanType, beanName);
      							// 判断@Aspect注解中标注的是否为singleton类型,默认的切面类都是singleton类型
      							if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
      								// 将BeanFactory和当前bean封装为MetadataAwareAspectInstanceFactory对象,这里会再次将@Aspect注解中的参数都封装为一个AspectMetadata,并且保存在该factory中
      								MetadataAwareAspectInstanceFactory factory =
      										new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
      								// 通过封装的bean获取其Advice,如@Before,@After等注解,并且将这些  Advice都解析并且封装为一个个的Advisor对象,这里是真正处理aop注解的入口方法。实际调用到ReflectiveAspectJAdvisorFactory的getAdvisors方法
      								List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
      								// 如果当前bean是单例的,那么将解析出来的Advisor对象缓存到advisorsCache中
      								if (this.beanFactory.isSingleton(beanName)) {
      									this.advisorsCache.put(beanName, classAdvisors);
      								}
      								else {
      									this.aspectFactoryCache.put(beanName, factory);
      								}
      								advisors.addAll(classAdvisors);
      							}
      							else {
      								// Per target or per this.
      								// 如果@Aspect注解标注的是perthis和pertarget类型,说明当前切面
      								// 不可能是单例的,因而这里判断其如果是单例的则抛出异常
      								if (this.beanFactory.isSingleton(beanName)) {
      									throw new IllegalArgumentException("Bean with name '" + beanName +
      											"' is a singleton, but aspect instantiation model is not singleton");
      								}
      								// 将当前BeanFactory和切面bean封装为一个多例类型的Factory
      								MetadataAwareAspectInstanceFactory factory =
      										new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
      								this.aspectFactoryCache.put(beanName, factory);
      								advisors.addAll(this.advisorFactory.getAdvisors(factory));
      							}
      						}
      					}
      					this.aspectBeanNames = aspectNames;
      					return advisors;
      				}
      			}
      		}
      
      		if (aspectNames.isEmpty()) {
      			return Collections.emptyList();
      		}
      		// 通过所有的aspectNames在缓存中获取切面对应的Advisor,这里如果是单例的,则直接从advisorsCache
      		// 获取,如果是多例类型的,则通过MetadataAwareAspectInstanceFactory立即生成一个
      		List<Advisor> advisors = new ArrayList<>();
      		for (String aspectName : aspectNames) {
      			List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
      			if (cachedAdvisors != null) {
      				advisors.addAll(cachedAdvisors);
      			}
      			// 如果是多例的Advisor bean,则通过MetadataAwareAspectInstanceFactory生成
      			else {
      				MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
      				advisors.addAll(this.advisorFactory.getAdvisors(factory));
      			}
      		}
          // 返回解析到的所有Advisor
      		return advisors;
      	}
      
  6. ReflectiveAspectJAdvisorFactory的getAdvisors方法

    1. 	@Override
      	public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
      		// 获取切面类的Class对象
      		Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
      		// 获取切面类的名字
      		String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
      		// 校验切面类,主要是判断其切点是否为perflow或者是percflowbelow,Spring暂时不支持这两种类型的切点
      		validate(aspectClass);
      
      		// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
      		// so that it will only instantiate once.
      		// 使用装饰器模式,主要是对获取到的切面实例进行了缓存,保证每次获取到的都是同一个切面实例
      		MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
      				new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
      
      		List<Advisor> advisors = new ArrayList<>();
      		// 这里getAdvisorMethods()会获取所有Advisor,然后按照通知的执行顺序进行排序并返回,这里按类进行分开处理的。这是对五种不同的通知进行了排序并返回。参见文章末尾。
      		for (Method method : getAdvisorMethods(aspectClass)) {
      			// Prior to Spring Framework 5.2.7, advisors.size() was supplied as the declarationOrderInAspect
      			// to getAdvisor(...) to represent the "current position" in the declared methods list.
      			// However, since Java 7 the "current position" is not valid since the JDK no longer
      			// returns declared methods in the order in which they are declared in the source code.
      			// Thus, we now hard code the declarationOrderInAspect to 0 for all advice methods
      			// discovered via reflection in order to support reliable advice ordering across JVM launches.
      			// Specifically, a value of 0 aligns with the default value used in
      			// AspectJPrecedenceComparator.getAspectDeclarationOrder(Advisor).
      			// 判断当前方法是否标注有@Before,@After或@Around等注解,如果标注了,则将其封装为一个Advisor
      			Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
      			if (advisor != null) {
      				advisors.add(advisor);
      			}
      		}
      
      		// If it's a per target aspect, emit the dummy instantiating aspect.
      
      		// 这里的isLazilyInstantiated()方法判断的是当前bean是否应该被延迟初始化,其主要是判断当前
      		// 切面类是否为perthis,pertarget或pertypewithiin等声明的切面。因为这些类型所环绕的目标bean
      		// 都是多例的,因而需要在运行时动态判断目标bean是否需要环绕当前的切面逻辑
      		if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
      			// 如果Advisor不为空,并且是需要延迟初始化的bean,则在第0位位置添加一个同步增强器,
      			// 该同步增强器实际上就是一个BeforeAspect的Advisor
      			Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
      			advisors.add(0, instantiationAdvisor);
      		}
      
      		// Find introduction fields.
      		// 判断属性上是否包含有@DeclareParents注解标注的需要新添加的属性,如果有,则将其封装为一个Advisor
      		for (Field field : aspectClass.getDeclaredFields()) {
      			Advisor advisor = getDeclareParentsAdvisor(field);
      			if (advisor != null) {
      				advisors.add(advisor);
      			}
      		}
      		return advisors;
      	}
      
  7. ReflectiveAspectJAdvisorFactory的getAdvisor方法(重载方法)

    1. 	@Override
      	@Nullable
      	public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
      			int declarationOrderInAspect, String aspectName) {
      		// 校验当前切面类是否使用了perflow或者percflowbelow标识的切点,Spring暂不支持这两种切点
      		validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
      
      		// 获取当前方法中@Before,@After或者@Around等标注的注解,并且获取该注解的值,将其
      		// 封装为一个AspectJExpressionPointcut对象,里面包含了切点表达式,切点方法等信息
      		AspectJExpressionPointcut expressionPointcut = getPointcut(
      				candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
      		if (expressionPointcut == null) {
      			return null;
      		}
      
      		// 将获取到的切点,切点方法等信息封装为一个Advisor对象,也就是说当前Advisor包含有所有 当前切面进行环绕所需要的信息。这里在InstantiationModelAwarePointcutAdvisorImpl的构造函数中会调用InstantiationModelAwarePointcutAdvisorImpl的instantiateAdvice方法。根据注解创建不同的Advice
      		return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
      				this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
      	}
      
  8. InstantiationModelAwarePointcutAdvisorImp的构造方法

    1. 	public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
      			Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
      			MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
      
      		// 切点表达式,如果是@Pointcut注解的方法,那么这里的declaredPointcut就是@Pointcut注解的方法
      		this.declaredPointcut = declaredPointcut;
      		// 切面类的Class对象
      		this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
      		// 切面类的方法名
      		this.methodName = aspectJAdviceMethod.getName();
      		// 切面类的方法参数类型
      		this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
      		// 切面类的方法, @Before、@After、@Around等注解的方法
      		this.aspectJAdviceMethod = aspectJAdviceMethod;
      		// aspectj的通知工厂,调用切面的方法,生成对应的通知
      		this.aspectJAdvisorFactory = aspectJAdvisorFactory;
      		// aspect的实例工厂
      		this.aspectInstanceFactory = aspectInstanceFactory;
      		// 切面的顺序
      		this.declarationOrder = declarationOrder;
      		// 切面的名称
      		this.aspectName = aspectName;
      
      		// 判断当前的切面对象是否需要延时加载
      		if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
      			// Static part of the pointcut is a lazy type.
      			Pointcut preInstantiationPointcut = Pointcuts.union(
      					aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
      
      			// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
      			// If it's not a dynamic pointcut, it may be optimized out
      			// by the Spring AOP infrastructure after the first evaluation.
      			this.pointcut = new PerTargetInstantiationModelPointcut(
      					this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
      			this.lazy = true;
      		}
      		else {
      			// A singleton aspect.
      			this.pointcut = this.declaredPointcut;
      			this.lazy = false;
      			// 将切面中的通知构造为advice通知对象 (将通知方法实例化为通知拦截器MethodInterceptor类)
      			this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
      		}
      	}
      
      
  9. InstantiationModelAwarePointcutAdvisorImp的instantiateAdvice方法,这里根据注解类型不同生成五种不同的通知(Advice)和Pointcut切面

    1. 	private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
      		// 入参为切点表达式类
      		// 这里调用ReflectiveAspectJAdvisorFactory的getAdvice方法
      		Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
      				this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
      		return (advice != null ? advice : EMPTY_ADVICE);
      	}
      
  10. ReflectiveAspectJAdvisorFactory的getAdvice方法,这里根据注解类型不同生成五种不同的通知(Advice)和Pointcut切面

    1. 	@Override
      	@Nullable
      	public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
      			MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
      		// 获取切面类的Class对象
      		Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
      		validate(candidateAspectClass);
      
      		// 获取切面方法上的注解
      		AspectJAnnotation<?> aspectJAnnotation =
      				AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
      		// 解析出来的注解信息是否为null
      		if (aspectJAnnotation == null) {
      			return null;
      		}
      
      		// If we get here, we know we have an AspectJ method.
      		// Check that it's an AspectJ-annotated class
      
      		// 再次判断是否是切面对象
      		if (!isAspect(candidateAspectClass)) {
      			throw new AopConfigException("Advice must be declared inside an aspect type: " +
      					"Offending method '" + candidateAdviceMethod + "' in class [" +
      					candidateAspectClass.getName() + "]");
      		}
      
      		if (logger.isDebugEnabled()) {
      			logger.debug("Found AspectJ method: " + candidateAdviceMethod);
      		}
      
      		AbstractAspectJAdvice springAdvice;
      
      		// 判断标注在方法上的注解类型
      		switch (aspectJAnnotation.getAnnotationType()) {
      
      			// 是PointCut注解,那么就抛出异常,因为在外面传递进来的方法已经排除了Pointcut的方法
      			case AtPointcut:
      				if (logger.isDebugEnabled()) {
      					logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
      				}
      				return null;
      			// 环绕通知,构建AspectJAroundAdvice
      			case AtAround:
      				springAdvice = new AspectJAroundAdvice(
      						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
      				break;
      			// 前置通知,构建AspectJMethodBeforeAdvice
      			case AtBefore:
      				springAdvice = new AspectJMethodBeforeAdvice(
      						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
      				break;
      			// 后置通知,AspectJAfterAdvice
      			case AtAfter:
      				springAdvice = new AspectJAfterAdvice(
      						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
      				break;
      			// 返回通知,AspectJAfterReturningAdvice
      			case AtAfterReturning:
      				springAdvice = new AspectJAfterReturningAdvice(
      						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
      				AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
      				if (StringUtils.hasText(afterReturningAnnotation.returning())) {
      					springAdvice.setReturningName(afterReturningAnnotation.returning());
      				}
      				break;
      			// 异常通知,AspectJAfterThrowingAdvice
      			case AtAfterThrowing:
      				springAdvice = new AspectJAfterThrowingAdvice(
      						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
      				AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
      				if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
      					springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
      				}
      				break;
      			default:
      				throw new UnsupportedOperationException(
      						"Unsupported advice type on method: " + candidateAdviceMethod);
      		}
      
      		// Now to configure the advice...
      		// 设置我们构建出来的通知对象的相关属性比如DeclarationOrder,在代理调用的时候,责任链顺序上会用到
      		springAdvice.setAspectName(aspectName);
      		springAdvice.setDeclarationOrder(declarationOrder);
      		String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
      		if (argNames != null) {
      			springAdvice.setArgumentNamesFromStringArray(argNames);
      		}
      		springAdvice.calculateArgumentBindings();
      
      		return springAdvice;
      	}
      

五种切面通知

  • beforeafteraroundafterReturnafterThrowing分别对应AspectJMethodBeforeAdviceAspectJAfterAdviceAspectJAroundAdviceAspectJAfterReturningAdviceAspectJAfterThrowingAdvice。五种不同的通知
  • 所有的方法通知调用都是通过invoke方法(实现MethodInterceptor接口覆写invoke方法)定义实现。但并不是所有的Advice都有invoke方法。其中AspectJAfterThrowingAdviceAspectJAfterAdviceAspectJAroundAdvice实现了MethodInterceptor接口。
  • AspectJMethodBeforeAdviceAspectJAfterReturningAdvice没有实现MethodInterceptor接口,需要通过DefaultAdvisorAdapterRegistry类通过adapter转换为MethodInterceptor接口的实现类,以便进行链式调用。(AspectJAfterReturningAdvice--AfterReturningAdviceInterceptor AspectJMethodBeforeAdvice-MethodBeforeAdviceInterceptor)
  • 为什么有的直接实现了MethodInterceptor接口,有的没有直接实现MethodInterceptor接口,需要我们通过adapter进行一次转换。AspectJMethodBeforeAdvice和AspectJAfterReturningAdvice这两个方法分别在目标方法调用之前和目标方法返回的时候调用。没有直接实现应该是方便我们进行二次扩展开发,实现自定义逻辑。

创建代理

AbstractAutoProxyCreator的createProxy方法

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
       @Nullable Object[] specificInterceptors, TargetSource targetSource) {

    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
       AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    }
    // 创建代理工厂
    ProxyFactory proxyFactory = new ProxyFactory();
    // 设置代理工厂的属性
    proxyFactory.copyFrom(this);
    // 如果需要直接代理目标类
    if (proxyFactory.isProxyTargetClass()) {
       // Explicit handling of JDK proxy targets (for introduction advice scenarios)
       // 如果当前beanClass是jdk动态代理类,则需要将其接口添加到代理工厂中
       if (Proxy.isProxyClass(beanClass)) {
          // Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
          for (Class<?> ifc : beanClass.getInterfaces()) {
             proxyFactory.addInterface(ifc);
          }
       }
    }
    else {
       // No proxyTargetClass flag enforced, let's apply our default checks...
       // 判断是否需要代理当前类,如果需要设置proxyTargetClass为true,后面会判断proxyTargetClass是否为true,如果为true则根据targetClass是否为Interface来决定走jdk还是cglib代理
       if (shouldProxyTargetClass(beanClass, beanName)) {
          proxyFactory.setProxyTargetClass(true);
       }
       else {
          // 添加代理接口
          evaluateProxyInterfaces(beanClass, proxyFactory);
       }
    }
    // 构建所有已经解析到Advisor通知器列表advisors
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    // 将advisors放入代理工厂
    proxyFactory.addAdvisors(advisors);
    // targetSource就是符合条件,需要被代理增强的类
    proxyFactory.setTargetSource(targetSource);
    // 定制代理工厂
    customizeProxyFactory(proxyFactory);
    // 控制代理工程被配置之后,是否还允许修改通知,默认值是false
    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
       proxyFactory.setPreFiltered(true);
    }

    // Use original ClassLoader if bean class not locally loaded in overriding class loader
    // 获取代理工厂的类加载器
    ClassLoader classLoader = getProxyClassLoader();
    if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
       classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
    }
    // 创建并获取真正的代理对象
    return proxyFactory.getProxy(classLoader);
}
public Object getProxy(@Nullable ClassLoader classLoader) {
		// 这里会调用CglibAopProxy的getProxy方法
    return createAopProxy().getProxy(classLoader);
}

CglibAopProxy的getProxy方法

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

    try {
       // 获得目标类的Class对象
       Class<?> rootClass = this.advised.getTargetClass();
       Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
       // 记录被代理类的Class对象
       Class<?> proxySuperClass = rootClass;
       // 如果当前目标类是CGLIB生成的代理类,则获取其父类,即目标类
       if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
          proxySuperClass = rootClass.getSuperclass();
          Class<?>[] additionalInterfaces = rootClass.getInterfaces();
          for (Class<?> additionalInterface : additionalInterfaces) {
             this.advised.addInterface(additionalInterface);
          }
       }

       // Validate the class, writing log messages as necessary.
       // 校验目标类的方法
       validateClassIfNecessary(proxySuperClass, classLoader);

       // Configure CGLIB Enhancer...
       // 创建CGLIB Enhancer对象
       Enhancer enhancer = createEnhancer();
       // 设置classLoader
       if (classLoader != null) {
          enhancer.setClassLoader(classLoader);
          if (classLoader instanceof SmartClassLoader &&
                ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
             enhancer.setUseCache(false);
          }
       }
       // 设置代理类进行的目标类对象及相关属性
       enhancer.setSuperclass(proxySuperClass);
       enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
       enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
       enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
       // 设置回调的拦截器链,这里很关键
       Callback[] callbacks = getCallbacks(rootClass);
       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
       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);
    }
}

CglibAopProxy的getCallbacks方法

通过getCallbacks方法,获取到rootClass所有符合条件切面回调方法。并生成一个Callback数组callbacks

    private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
       // Parameters used for optimization choices...
       // 是否暴露代理对象
       boolean exposeProxy = this.advised.isExposeProxy();
       // 是否冻结
       boolean isFrozen = this.advised.isFrozen();
//     boolean isFrozen = true;
       // 目标类是否是静态的
       boolean isStatic = this.advised.getTargetSource().isStatic();

       // Choose an "aop" interceptor (used for AOP calls).
       /**
        * 将生成DynamicAdvisedInterceptor,这个拦截器是用来处理AOP调用的,它持有了AdvisedSupport对象,也就是我们定义的所有的Advisor
        * 很重要,后面生成字节码之后,会在相应的方法之后插入这个拦截器,也就是说,所有符合条件的方法前后都会插入这个			    DynamicAdvisedInterceptor这个类的intercept方法,会根据我们定义的Advisor,来决定调用哪些advice
        */
       Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

       // Choose a "straight to target" interceptor. (used for calls that are
       // unadvised but can return this). May be required to expose the proxy.
       Callback targetInterceptor;
       // 如果暴露代理对象
       if (exposeProxy) {
          // 如果需要提前暴露代理对象,根据是否是静态的目标类,创建不同的拦截器,然后放入到ThreadLocal中,方便当前线程获取
          targetInterceptor = (isStatic ?
                new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
                new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
       }
       // 如果不需要暴露代理对象,根据是否是静态的目标类,创建不同的拦截器
       else {
          targetInterceptor = (isStatic ?
                new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
                new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
       }

       // Choose a "direct to target" dispatcher (used for
       // unadvised calls to static targets that cannot return this).
       // 创建一个直接调用目标类的拦截器
       Callback targetDispatcher = (isStatic ?
             new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());

       Callback[] mainCallbacks = new Callback[] {
             aopInterceptor,  // for normal 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),
             new HashCodeInterceptor(this.advised)
       };

       Callback[] callbacks;

       // If the target is a static one and the advice chain is frozen,
       // then we can make some optimizations by sending the AOP calls
       // direct to the target using the fixed chain for that method.
       /**
        * 如果目标类是静态的,并且代理对象已经冻结,说明我们不会再修改代理对象
        * 那么我们可以通过使用固定的拦截器链,将AOP调用直接发送到目标类,从而进行一些优化
        */
       if (isStatic && isFrozen) {
          // 获取目标类的method列表
          Method[] methods = rootClass.getMethods();
          // 创建一个固定的拦截器数组
          Callback[] fixedCallbacks = new Callback[methods.length];
          // 创建一个固定的拦截器map,记录方法名和下标
          this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);

          // TODO: small memory optimization here (can skip creation for methods with no advice)
          // 遍历目标类方法列表,根据我们设置的切面配置,为每个方法创建一个拦截器链,这个拦截器链里面保存了所有符合条件的advice
          for (int x = 0; x < methods.length; x++) {
             Method method = methods[x];
             List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
             fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
                   chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
             this.fixedInterceptorMap.put(method, x);
          }

          // Now copy both the callbacks from mainCallbacks
          // and fixedCallbacks into the callbacks array.
          callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
          System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
          System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
          this.fixedInterceptorOffset = mainCallbacks.length;
       }
       else {
          callbacks = mainCallbacks;
       }
       return callbacks;
    }

image-20231004114326635转存失败,建议直接上传图片文件

这个callbacks数组的第一个元素就是CglibAopProxy的内部类DynamicAdvisedInterceptor。在通过字节码写入的时候讲这个类织入了生成后的代理类的目标方法中。

image-20231005093143991转存失败,建议直接上传图片文件

public final Integer add(Integer var1, Integer var2) {
  	// 给var10000赋值。这是一个MethodInterceptor
    MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
  	// 如果此时var10000为null。初始化CGLIB$CALLBACK_0。再次赋值
    if (var10000 == null) {
        CGLIB$BIND_CALLBACKS(this);
        var10000 = this.CGLIB$CALLBACK_0;
    }
		// 如果var10000不为空。调用var10000的intercept方法。这个var10000实际上就是DynamicAdvisedInterceptor
    return var10000 != null ? (Integer)var10000.intercept(this, CGLIB$add$0$Method, new Object[]{var1, var2}, CGLIB$add$0$Proxy) : super.add(var1, var2);
}

这动态代理生成后的add方法(add为自定义方法)。可以看到首先将this.CGLIBCALLBACK0赋值给var10000,如果var10000null。调用CGLIBCALLBACK_0赋值给var10000,如果var10000是null。调用CGLIBBIND_CALLBACKS方法初始化CGLIB$CALLBACK_0。然后再次赋值给var10000。

CGLIBBINDCALLBACKS方法完成对CGLIBBIND_CALLBACKS方法完成对CGLIBCALLBACK_0一直到CGLIBCALLBACK6完成赋值。这里var10000CGLIBCALLBACK_6完成赋值。这里var10000是CGLIBSTATIC_CALLBACKS,实际上就是上面截图中的callbacks。

image-20231005094008608转存失败,建议直接上传图片文件

核心数据结构-栈

整个切面执行流程,就是先把所有符合条件的Advisor有序的入栈,入栈之后然后依次出栈,在出栈过程中完成通过反射调用Advisor定义的增强逻辑,最终完成切面整个调用过程。

核心类

DynamicAdvisedInterceptor aop代理的入口
  • spring容器启动之后,再调用符合代理方法时会进入这个intercept方法进行代理处理。
  • 最重要的步骤是List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); 获取拦截器处理链。然后根据拦 截器链完成切面处理。
  • DynamicAdvisedInterceptor类代码
  • private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
    
        private final AdvisedSupport advised;
    
        public DynamicAdvisedInterceptor(AdvisedSupport advised) {
           this.advised = advised;
        }
        @Override
        @Nullable
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
           Object oldProxy = null;
           // 获取当前线程的代理对象
           boolean setProxyContext = false;
           // 目标对象
           Object target = null;
           // 获取目标对象的Class对象
           TargetSource targetSource = this.advised.getTargetSource();
           try {
              if (this.advised.exposeProxy) {
                 // Make invocation available if necessary.
                 oldProxy = AopContext.setCurrentProxy(proxy);
                 setProxyContext = true;
              }
              // Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
              // 获取目标对象
              target = targetSource.getTarget();
              // 获取目标对象的Class对象
              Class<?> targetClass = (target != null ? target.getClass() : null);
              // 获取方法的拦截器链。非常关键,后面就是在这个chain拦截链上完成对目标方法的切面处理。
              List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
              Object retVal;
              // Check whether we only have one InvokerInterceptor: that is,
              // no real advice, but just reflective invocation of the target.
              // 如果拦截器链为空,并且方法是public的,那么可以直接调用目标对象的方法,不需要创建MethodInvocation
              if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
                	// 获取参数列表
                 Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                 retVal = methodProxy.invoke(target, argsToUse);
              }
              else {
                 // We need to create a method invocation...
                 // 创建一个CglibMethodInvocation对象,这个对象持有了目标对象,目标类,方法,参数,拦截器链等信息,用于调用目标方法,这里最终会调用到ReflectiveMethodInvocation的proceed方法
                 retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
              }
              retVal = processReturnType(proxy, target, method, retVal);
              return retVal;
           }
           finally {
              if (target != null && !targetSource.isStatic()) {
                 targetSource.releaseTarget(target);
              }
              if (setProxyContext) {
                 // Restore old proxy.
                 AopContext.setCurrentProxy(oldProxy);
              }
           }
        }
    
        @Override
        public boolean equals(@Nullable Object other) {
           return (this == other ||
                 (other instanceof DynamicAdvisedInterceptor &&
                       this.advised.equals(((DynamicAdvisedInterceptor) other).advised)));
        }
    
        /**
         * CGLIB uses this to drive proxy creation.
         */
        @Override
        public int hashCode() {
           return this.advised.hashCode();
        }
    }
    
    • 生成拦截器链的核心方法(DefaultAdvisorChainFactory的getInterceptorsAndDynamicInterceptionAdvice方法)
    @Override
    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.
        // 这里用了一个单例模式 获取DefaultAdvisorAdapterRegistry实例
        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
        // 获取所有的Advisor通知期
        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) {
           // 如果是PointcutAdvisor类型的,就是通过切点来进行匹配的
           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;
                 //检测Advisor是否适用于此目标方法。这里会根据切面表达式的不同,来使用不同的匹配器
                 if (mm instanceof IntroductionAwareMethodMatcher) {
                    if (hasIntroductions == null) {
                       hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
                    }
                    match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
                 }
                 else {
                    match = mm.matches(method, actualClass);
                 }
                 // 如果匹配的话,就将Advisor转换为MethodInterceptor
                 if (match) {
                    // 通过AdvisorAdapterRegistry中注册的AdvisorAdapter对Advisor进行转换
                    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));
                    }
                 }
              }
           }
           // 如果是IntroductionAdvisor类型的,就是通过IntroductionAdvisor来进行匹配的
           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;
    }
    

    image-20231005112536564转存失败,建议直接上传图片文件

    CglibMethodInvocation 开始进入代理处理流程
    • CglibMethodInvocation类代码
    	private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
    
    		@Nullable
    		private final MethodProxy methodProxy;
    
    		public  CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
    				Object[] arguments, @Nullable Class<?> targetClass,
    				List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
    			// 这里直接调用了ReflectiveMethodInvocation的构造方法
    			super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
    			// Only use method proxy for public methods not derived from java.lang.Object
    			// 这是只处理不是从java.lang.Object派生的公共方法使用方法代理
    			this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
    					method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
    					!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
    					methodProxy : null);
    		}
    
    		@Override
    		@Nullable
    		public Object proceed() throws Throwable {
    			try {
    				// 这里调用了ReflectiveMethodInvocation的proceed方法,实际上最终是ReflectiveMethodInvocation完成了方法的调用
    				return super.proceed();
    			}
    			catch (RuntimeException ex) {
    				throw ex;
    			}
    			catch (Exception ex) {
    				if (ReflectionUtils.declaresException(getMethod(), ex.getClass()) ||
    						KotlinDetector.isKotlinType(getMethod().getDeclaringClass())) {
    					// Propagate original exception if declared on the target method
    					// (with callers expecting it). Always propagate it for Kotlin code
    					// since checked exceptions do not have to be explicitly declared there.
    					throw ex;
    				}
    				else {
    					// Checked exception thrown in the interceptor but not declared on the
    					// target method signature -> apply an UndeclaredThrowableException,
    					// aligned with standard JDK dynamic proxy behavior.
    					throw new UndeclaredThrowableException(ex);
    				}
    			}
    		}
    
    		/**
    		 * 完成目标方法的调用
    		 */
    		@Override
    		protected Object invokeJoinpoint() throws Throwable {
    			if (this.methodProxy != null) {
    				return this.methodProxy.invoke(this.target, this.arguments);
    			}
    			else {
    				return super.invokeJoinpoint();
    			}
    		}
    	}
    
    • CglibMethodInvocation是一个静态内部类,位于CglibAopProxy中。继承ReflectiveMethodInvocation。CglibMethodInvocation的主要功能就是对ReflectiveMethodInvocation进行了包装,实例化ReflectiveMethodInvocation。并调用ReflectiveMethodInvocation的相关方法。
    ReflectiveMethodInvocation 完成代理的链式调用
    • 因为在CglibMethodInvocation的构造方法里面调用了ReflectiveMethodInvocation的构造方法,所以ReflectiveMethodInvocation实例持有完成代理调用的很多信息,包括interceptorsAndDynamicMethodMatchers拦截器链(实际上就是DynamicAdvisedIntercept的intercept方法的List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass)获取的chain数组),目标方法参数等关键信息。所以能够完成chain的链式调用
    • 在proceed()方法中找到当前要调用的拦截器,通过反射((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this)完成Advisor的拦截调用时,将当前对象传入了调用对象的MethodInteceptor中。而当前对象持有了拦截器链,目标对象等关键信息才能完成链式调用。
    • 比如下面这个AspectJAfterAdvice,我们通过反射调用invoke方法时,invoke方法的参数MethodInvocation实际上就是ReflectiveMethodInvocation实例。铜在invoke方法中调用mi.prceed()之后最终又会回到ReflectiveMethodInvocation的prceed()方法。在进入ReflectiveMethodInvocation的prceed()方法之后会通过currentInterceptorIndex这个索引下标位置来判断是否完成拦截器链的所有拦截器调用。如果没有完成则进入下一个拦截器调用。
    • 对于aroundAdvice环绕通知,在定义方法时有一个ProceedingJoinPoint类型参数pjp,并在方法内部调用pjp.proceed(); 在AspectJAroundAdvice中,实际上ProceedingJoinPoint里面包含了ReflectiveMethodInvocation实例。所以调用pjp.proceed()方法仍会进入ReflectiveMethodInvocation的proceed继续查找下一个拦截器链完成调用。
    • // 定义环绕通知
      @Around("pointcut()")
      public Object around(ProceedingJoinPoint pjp) throws Throwable {
          System.out.println("AspectTestOne around before");
          Object proceed = pjp.proceed();
          System.out.println("AspectTestOne around after");
          return proceed;
      }
      
      // 环绕通知处理类
      public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {
      
          public AspectJAroundAdvice(
                Method aspectJAroundAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
      
             super(aspectJAroundAdviceMethod, pointcut, aif);
          }
      
      
          @Override
          public boolean isBeforeAdvice() {
             return false;
          }
      
          @Override
          public boolean isAfterAdvice() {
             return false;
          }
      
          @Override
          protected boolean supportsProceedingJoinPoint() {
             return true;
          }
      
          @Override
          @Nullable
          public Object invoke(MethodInvocation mi) throws Throwable {
             if (!(mi instanceof ProxyMethodInvocation)) {
                throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
             }
             ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
             ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
             JoinPointMatch jpm = getJoinPointMatch(pmi);
             return invokeAdviceMethod(pjp, jpm, null, null);
          }
      
          /**
           * Return the ProceedingJoinPoint for the current invocation,
           * instantiating it lazily if it hasn't been bound to the thread already.
           * @param rmi the current Spring AOP ReflectiveMethodInvocation,
           * which we'll use for attribute binding
           * @return the ProceedingJoinPoint to make available to advice methods
           */
          protected ProceedingJoinPoint lazyGetProceedingJoinPoint(ProxyMethodInvocation rmi) {
             return new MethodInvocationProceedingJoinPoint(rmi);
          }
      
      }
      
      // @After注解修饰方法最终生成的Advice 
      public class AspectJAfterAdvice extends AbstractAspectJAdvice
             implements MethodInterceptor, AfterAdvice, Serializable {
      
          public AspectJAfterAdvice(
                Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
      
             super(aspectJBeforeAdviceMethod, pointcut, aif);
          }
      
      
          @Override
          @Nullable
          public Object invoke(MethodInvocation mi) throws Throwable {
             try {
                return mi.proceed();
             }
             finally {
                invokeAdviceMethod(getJoinPointMatch(), null, null);
             }
          }
      
          @Override
          public boolean isBeforeAdvice() {
             return false;
          }
      
          @Override
          public boolean isAfterAdvice() {
             return true;
          }
      
      }
      
      // ReflectiveMethodInvocation类代码
      public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
      
          // 代理对象
          protected final Object proxy;
      
          @Nullable
          protected final Object target;
      
          // 目标方法
          protected final Method method;
      
          // 目标方法参数
          protected Object[] arguments;
      
          // 目标类
      
          @Nullable
          private final Class<?> targetClass;
      
          /**
           * Lazily initialized map of user-specific attributes for this invocation.
           */
          @Nullable
          private Map<String, Object> userAttributes;
      
          /**
           * 拦截器链(也就是我们定义好的Advisor),包含了所有的拦截器和动态匹配器
           *
           * List of MethodInterceptor and InterceptorAndDynamicMethodMatcher
           * that need dynamic checks.
           */
          protected final List<?> interceptorsAndDynamicMethodMatchers;
      
          /**
           * 正在调用的拦截器的索引下标
           *
           * Index from 0 of the current interceptor we're invoking.
           * -1 until we invoke: then the current interceptor.
           */
          private int currentInterceptorIndex = -1;
      
      
          /**
           * 创建一个新的ReflectiveMethodInvocation实例。保存了代理对象、目标对象、目标方法、目标方法参数、目标类、拦截器链等信息
           *
           * Construct a new ReflectiveMethodInvocation with the given arguments.
           * @param proxy the proxy object that the invocation was made on
           * @param target the target object to invoke
           * @param method the method to invoke
           * @param arguments the arguments to invoke the method with
           * @param targetClass the target class, for MethodMatcher invocations
           * @param interceptorsAndDynamicMethodMatchers interceptors that should be applied,
           * along with any InterceptorAndDynamicMethodMatchers that need evaluation at runtime.
           * MethodMatchers included in this struct must already have been found to have matched
           * as far as was possibly statically. Passing an array might be about 10% faster,
           * but would complicate the code. And it would work only for static pointcuts.
           */
          protected ReflectiveMethodInvocation(
                Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,
                @Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
      
             this.proxy = proxy;
             this.target = target;
             this.targetClass = targetClass;
             this.method = BridgeMethodResolver.findBridgedMethod(method);
             this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
             this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
          }
      
      
          @Override
          public final Object getProxy() {
             return this.proxy;
          }
      
          @Override
          @Nullable
          public final Object getThis() {
             return this.target;
          }
      
          @Override
          public final AccessibleObject getStaticPart() {
             return this.method;
          }
      
          /**
           * Return the method invoked on the proxied interface.
           * May or may not correspond with a method invoked on an underlying
           * implementation of that interface.
           */
          @Override
          public final Method getMethod() {
             return this.method;
          }
      
          @Override
          public final Object[] getArguments() {
             return this.arguments;
          }
      
          @Override
          public void setArguments(Object... arguments) {
             this.arguments = arguments;
          }
      
      
          //核心方法。这个方法通过currentInterceptorIndex找到对应的拦截器,然后调用拦截器的invoke方法。因为所有的chain第一个元素都是ExposeInvocationInterceptor,所以第一个调用的是ExposeInvocationInterceptor。
          @Override
          @Nullable
          public Object proceed() throws Throwable {
             // We start with an index of -1 and increment early.
             if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
               	// 说明所有的拦截器都完成调用。开始调用目标方法。
                return invokeJoinpoint();
             }
             // 获取下一个要执行的拦截器,沿着定义好的interceptorOrInterceptionAdvice链进行处理
             // 第一个拦截器就是ExposeInvocationInterceptor
             Object interceptorOrInterceptionAdvice =
                   this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
             // 如果是InterceptorAndDynamicMethodMatcher类型的实例
             if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
                // Evaluate dynamic method matcher here: static part will already have
                // been evaluated and found to match.
                // 这里对拦截器进行动态匹配的判断,这里是对pointcut触发进行匹配的地方,如果和定义的pointcut匹配,那么这个advice将会得到执行
                InterceptorAndDynamicMethodMatcher dm =
                      (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
                Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
                if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
                   return dm.interceptor.invoke(this);
                }
                else {
                   // Dynamic matching failed.
                   // Skip this interceptor and invoke the next in the chain.
                   // 如果不匹配,那么proceed会被递归调用
                   return proceed();
                }
             }
             else {
                // It's an interceptor, so we just invoke it: The pointcut will have
                // been evaluated statically before this object was constructed.
                // 普通拦截器,直接调用拦截器,将this作为参数传递以保证当前实例中调用链的执行。
                return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
             }
          }
      
          /**
           * Invoke the joinpoint using reflection.
           * Subclasses can override this to use custom invocation.
           * @return the return value of the joinpoint
           * @throws Throwable if invoking the joinpoint resulted in an exception
           */
          @Nullable
          protected Object invokeJoinpoint() throws Throwable {
             return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
          }
      
      
          /**
           * This implementation returns a shallow copy of this invocation object,
           * including an independent copy of the original arguments array.
           * <p>We want a shallow copy in this case: We want to use the same interceptor
           * chain and other object references, but we want an independent value for the
           * current interceptor index.
           * @see java.lang.Object#clone()
           */
          @Override
          public MethodInvocation invocableClone() {
             Object[] cloneArguments = this.arguments;
             if (this.arguments.length > 0) {
                // Build an independent copy of the arguments array.
                cloneArguments = this.arguments.clone();
             }
             return invocableClone(cloneArguments);
          }
      
          /**
           * This implementation returns a shallow copy of this invocation object,
           * using the given arguments array for the clone.
           * <p>We want a shallow copy in this case: We want to use the same interceptor
           * chain and other object references, but we want an independent value for the
           * current interceptor index.
           * @see java.lang.Object#clone()
           */
          @Override
          public MethodInvocation invocableClone(Object... arguments) {
             // Force initialization of the user attributes Map,
             // for having a shared Map reference in the clone.
             if (this.userAttributes == null) {
                this.userAttributes = new HashMap<>();
             }
      
             // Create the MethodInvocation clone.
             try {
                ReflectiveMethodInvocation clone = (ReflectiveMethodInvocation) clone();
                clone.arguments = arguments;
                return clone;
             }
             catch (CloneNotSupportedException ex) {
                throw new IllegalStateException(
                      "Should be able to clone object of type [" + getClass() + "]: " + ex);
             }
          }
      
      
          @Override
          public void setUserAttribute(String key, @Nullable Object value) {
             if (value != null) {
                if (this.userAttributes == null) {
                   this.userAttributes = new HashMap<>();
                }
                this.userAttributes.put(key, value);
             }
             else {
                if (this.userAttributes != null) {
                   this.userAttributes.remove(key);
                }
             }
          }
      
          @Override
          @Nullable
          public Object getUserAttribute(String key) {
             return (this.userAttributes != null ? this.userAttributes.get(key) : null);
          }
      
          /**
           * Return user attributes associated with this invocation.
           * This method provides an invocation-bound alternative to a ThreadLocal.
           * <p>This map is initialized lazily and is not used in the AOP framework itself.
           * @return any user attributes associated with this invocation
           * (never {@code null})
           */
          public Map<String, Object> getUserAttributes() {
             if (this.userAttributes == null) {
                this.userAttributes = new HashMap<>();
             }
             return this.userAttributes;
          }
      
      
          @Override
          public String toString() {
             // Don't do toString on target, it may be proxied.
             StringBuilder sb = new StringBuilder("ReflectiveMethodInvocation: ");
             sb.append(this.method).append("; ");
             if (this.target == null) {
                sb.append("target is null");
             }
             else {
                sb.append("target is of class [").append(this.target.getClass().getName()).append(']');
             }
             return sb.toString();
          }
      
      }
      

      单个切面正常调用顺序

      单个切面调用顺序.jpg

      单个切面目标方法出现异常

      目标方法出现异常调用顺序.jpg

      • 无论目标方法会不会出现异常。before前置通知一定会执行。定义在AspectJAroundAdvice方法中pjp.proceed()方法之前的代码也一定会调用。
      • after方法一定会被执行,因为AspectJAfterAdvice的mi.proceed()被try-finally代码块包裹。after方法调用是在finally代码块中被调用

      多个切面调用顺序

      多个切面调用顺序.jpg

      ExposeInvocationInterceptor 暴露出当前正在使用的ReflectiveMethodInvocation实例,用于后续的切面方法调用。

      比如在AbstractAspectJAdvice中的invoke方法中会获取当前ThreadLocal中保存的当前线程的ReflectiveMethodInvocation实例。

      public final class ExposeInvocationInterceptor implements MethodInterceptor, PriorityOrdered, Serializable {
      
      	/** Singleton instance of this class. */
      	public static final ExposeInvocationInterceptor INSTANCE = new ExposeInvocationInterceptor();
      
      	/**
      	 * Singleton advisor for this class. Use in preference to INSTANCE when using
      	 * Spring AOP, as it prevents the need to create a new Advisor to wrap the instance.
      	 */
      	public static final Advisor ADVISOR = new DefaultPointcutAdvisor(INSTANCE) {
      		@Override
      		public String toString() {
      			return ExposeInvocationInterceptor.class.getName() +".ADVISOR";
      		}
      	};
      
      	private static final ThreadLocal<MethodInvocation> invocation =
      			new NamedThreadLocal<>("Current AOP method invocation");
      
      
      	/**
      	 * Return the AOP Alliance MethodInvocation object associated with the current invocation.
      	 * @return the invocation object associated with the current invocation
      	 * @throws IllegalStateException if there is no AOP invocation in progress,
      	 * or if the ExposeInvocationInterceptor was not added to this interceptor chain
      	 */
      	public static MethodInvocation currentInvocation() throws IllegalStateException {
      		MethodInvocation mi = invocation.get();
      		if (mi == null) {
      			throw new IllegalStateException(
      					"No MethodInvocation found: Check that an AOP invocation is in progress and that the " +
      					"ExposeInvocationInterceptor is upfront in the interceptor chain. Specifically, note that " +
      					"advices with order HIGHEST_PRECEDENCE will execute before ExposeInvocationInterceptor! " +
      					"In addition, ExposeInvocationInterceptor and ExposeInvocationInterceptor.currentInvocation() " +
      					"must be invoked from the same thread.");
      		}
      		return mi;
      	}
      
      
      	/**
      	 * Ensures that only the canonical instance can be created.
      	 */
      	private ExposeInvocationInterceptor() {
      	}
      
      	@Override
      	@Nullable
      	public Object invoke(MethodInvocation mi) throws Throwable {
          // 获取当前正在处理的ReflectiveMethodInvocation实例
      		MethodInvocation oldInvocation = invocation.get();
          // 保存当前线程正在使用的ReflectiveMethodInvocation实例
      		invocation.set(mi);
      		try {
      			return mi.proceed();
      		}
      		finally {
            // 出现异常则保存为过去的ReflectiveMethodInvocation实例
      			invocation.set(oldInvocation);
      		}
      	}
      
      	@Override
      	public int getOrder() {
      		return PriorityOrdered.HIGHEST_PRECEDENCE + 1;
      	}
      
      	/**
      	 * Required to support serialization. Replaces with canonical instance
      	 * on deserialization, protecting Singleton pattern.
      	 * <p>Alternative to overriding the {@code equals} method.
      	 */
      	private Object readResolve() {
      		return INSTANCE;
      	}
      
      }
      
      AbstractAspectJAdvice 通知的抽象类,根据 AspectJ 注解生成Advice并完成切面方法调用
      五种通知的执行顺序

      在ReflectiveAspectJAdvisorFactory中有一个静态代码块。定义了五种通知的比较器。

      static {
          /**
           * 注意:尽管@After是在@AfterReturning@AfterThrowing之前排序的,但由于AspectJAfterAdvice.invoke(MethodInvocation)在“try”块中调用processed()
           * 而只在相应的“finally”块中引用@After建议方法,@After通知方法实际上将在@After Returning和@AfterThrowing方法之后调用
           */
          // Note: although @After is ordered before @AfterReturning and @AfterThrowing,
          // an @After advice method will actually be invoked after @AfterReturning and
          // @AfterThrowing methods due to the fact that AspectJAfterAdvice.invoke(MethodInvocation)
          // invokes proceed() in a `try` block and only invokes the @After advice method
          // in a corresponding `finally` block.
          Comparator<Method> adviceKindComparator = new ConvertingComparator<>(
                new InstanceComparator<>(
                      Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
                (Converter<Method, Annotation>) method -> {
                   AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
                   return (ann != null ? ann.getAnnotation() : null);
                });
          Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
          adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator);
      }