Java教程

Spring Aop源码流程分析

本文主要是介绍Spring Aop源码流程分析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1.准备环境

1.基于注解

1.引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zzhua</groupId>
    <artifactId>Aop-learn</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <spring.version>4.3.12.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>

    </dependencies>
</project>

2.目标类Calculator

public class Calculator {

    @Logger
    public int calculate(int x,int y,String name){
        System.out.println("目标方法运行...");
        return x/y;
    }

    public Calculator() {
        System.out.println("caculator构造方法...");
    }

}

3.切面类LogAspects

/**
 * 切面类
 * @Aspect: 告诉Spring当前类是一个切面类
 */
@Aspect
public class LogAspects {

    public LogAspects() {
        System.out.println("LogAspects构造方法...");
    }


    //抽取公共的切入点表达式
    //1、本类引用
    //2、其他的切面引用
    //@Pointcut("execution(public int com.zzhua.aop.Caculator.*(..))")
    @Pointcut("@annotation(com.zzhua.aop.Logger)")
    public void pointCut(){}


    @Before(value = "pointCut()")
    public void before(JoinPoint joinPoint){
        System.out.println("------------------------------前置通知 @Before开始");
        System.out.println(joinPoint.getArgs());// 传入的参数

        Signature signature = joinPoint.getSignature(); // 获取方法签名
        System.out.println(signature);

        Object target = joinPoint.getTarget();// 获取目标对象
        System.out.println(target.getClass());

        System.out.println("------------------------------前置通知 @Before结束");

    }


    @After(value = "com.zzhua.aop.LogAspects.pointCut()")
    public void logEnd(JoinPoint joinPoint){
        System.out.println("------------------------------后置通知 @After开始");
        System.out.println(joinPoint.getSignature().getName()+ "结束...");
        System.out.println("------------------------------后置通知 @After结束");

    }

    //JoinPoint必须在参数表的第一位
    @AfterReturning(value="pointCut()",returning="result")
    public void logReturn(JoinPoint joinPoint,Object result){
        System.out.println("------------------------------返回通知 @AfterReturning开始");
        System.out.println(joinPoint.getSignature().getName()+ "正常返回,运行结果:{"+result+"}");
        System.out.println("------------------------------返回通知 @AfterReturning结束");
    }

    //JoinPoint必须在参数表的第一位
    @AfterThrowing(value="pointCut()",throwing="exception")
    public void logException(JoinPoint joinPoint,Exception exception){
        System.out.println("------------------------------异常通知 @AfterThrowing开始");
        System.out.println(joinPoint.getSignature().getName()+ "异常...(异常信息:{"+exception+"}");
        System.out.println("------------------------------异常通知 @AfterThrowing开始");
    }

    @Around(value = "pointCut()")
    public Object logAround(ProceedingJoinPoint pjp){
        System.out.println("------------------------------环绕通知 @Around开始");
        try {
            System.out.println(pjp.getSignature().getName()+",参数列表:"+Arrays.asList(pjp.getArgs()));
            Object result = pjp.proceed();
            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("------------------------------环绕通知 @AAround结束");
        return null;
    }

}

4.配置类AopConfig

@Configuration
@EnableAspectJAutoProxy // 开启Aop功能
@ComponentScan("com.zzhua.aop")
public class AopConfig {

    @Bean
    public Calculator caculator(){
        return new Calculator();
    }

    @Bean
    public LogAspects aspect(){ // 切面bean必须加入spring容器当中
        return new LogAspects();
    }


}

5.测试类

public class AopTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context 
                                      = new AnnotationConfigApplicationContext(AopConfig.class);
        Calculator caculator = (Calculator) context.getBean("caculator");
        int result = caculator.calculate(4, 2,"zzhua");
        System.out.println("========代理调用方法结束=========");
    }
}

测试结果

目标方法正常执行结果

caculator构造方法...
LogAspects构造方法...
------------------------------环绕通知 @Around开始
calculate,参数列表:[4, 2, zzhua]
------------------------------前置通知 @Before开始
[Ljava.lang.Object;@3c947bc5
int com.zzhua.aop.Calculator.calculate(int,int,String)
class com.zzhua.aop.Calculator
------------------------------前置通知 @Before结束
目标方法运行...
------------------------------后置通知 @After开始
calculate结束...
------------------------------后置通知 @After结束
------------------------------返回通知 @AfterReturning开始
calculate正常返回,运行结果:{2}
------------------------------返回通知 @AfterReturning结束
========代理调用方法结束=========

目标方法执行发生异常

caculator构造方法...
LogAspects构造方法...
------------------------------环绕通知 @Around开始
calculate,参数列表:[4, 0, zzhua]
------------------------------前置通知 @Before开始
[Ljava.lang.Object;@3c947bc5
int com.zzhua.aop.Calculator.calculate(int,int,String)
class com.zzhua.aop.Calculator
------------------------------前置通知 @Before结束
目标方法运行...
java.lang.ArithmeticException: / by zero
	at com.zzhua.aop.Calculator.calculate(Calculator.java:9)
	at com.zzhua.aop.Calculator$$FastClassBySpringCGLIB$$39127855.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
	...
	at com.zzhua.aop.Calculator$$EnhancerBySpringCGLIB$$2ad149bc.calculate(<generated>)
	at com.zzhua.AopTest.main(AopTest.java:11)
------------------------------环绕通知 @AAround结束
------------------------------后置通知 @After开始
calculate结束...
------------------------------后置通知 @After结束
------------------------------返回通知 @AfterReturning开始
calculate正常返回,运行结果:{null}
------------------------------返回通知 @AfterReturning结束
Exception in thread "main" org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: public int com.zzhua.aop.Calculator.calculate(int,int,java.lang.String)
	at org.springframework.aop.framework.CglibAopProxy.processReturnType(CglibAopProxy.java:391)
	at org.springframework.aop.framework.CglibAopProxy.access$000(CglibAopProxy.java:82)
	...
	at com.zzhua.aop.Calculator$$EnhancerBySpringCGLIB$$2ad149bc.calculate(<generated>)
	at com.zzhua.AopTest.main(AopTest.java:11)

2.初步分析

结论

/**
 * AOP:【动态代理】
 * 		指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式;
 * 
 * 1、导入aop模块;Spring AOP:(spring-aspects)
 * 2、定义一个业务逻辑类(MathCalculator)
      ;在业务逻辑运行的时候将日志进行打印(方法之前、方法运行结束、方法出现异常,xxx)
 * 3、定义一个日志切面类(LogAspects):切面类里面的方法需要动态感知MathCalculator.div运行到哪里然后执行;
 * 		通知方法:
 * 			前置通知(@Before):logStart:在目标方法(div)运行之前运行
 * 			后置通知(@After):logEnd:在目标方法(div)运行结束之后运行(无论方法正常结束还是异常结束)
 * 			返回通知(@AfterReturning):logReturn:在目标方法(div)正常返回之后运行
 * 			异常通知(@AfterThrowing):logException:在目标方法(div)出现异常以后运行
 * 			环绕通知(@Around):动态代理,手动推进目标方法运行(joinPoint.procced())
 * 4、给切面类的目标方法标注何时何地运行(通知注解);
 * 5、将切面类和业务逻辑类(目标方法所在类)都加入到容器中;
 * 6、必须告诉Spring哪个类是切面类(给切面类上加一个注解:@Aspect)
 * [7]、给配置类中加 @EnableAspectJAutoProxy 【开启基于注解的aop模式】
 * 		在Spring中很多的 @EnableXXX;
 * 
 * 三步:
 * 	1)、将业务逻辑组件和切面类都加入到容器中;告诉Spring哪个是切面类(@Aspect)
 * 	2)、在切面类上的每一个通知方法上标注通知注解,告诉Spring何时何地运行(切入点表达式)
 *  3)、开启基于注解的aop模式;@EnableAspectJAutoProxy
 *  
 * AOP原理:【看给容器中注册了什么组件,这个组件什么时候工作,这个组件的功能是什么?】
 * 		@EnableAspectJAutoProxy;
 * 1、@EnableAspectJAutoProxy是什么?
 * 		@Import(AspectJAutoProxyRegistrar.class):给容器中导入AspectJAutoProxyRegistrar
 * 			利用AspectJAutoProxyRegistrar自定义给容器中注册bean;BeanDefinetion
 * 			internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator
 * 
 * 		给容器中注册一个AnnotationAwareAspectJAutoProxyCreator;
 * 
 * 2、 AnnotationAwareAspectJAutoProxyCreator:
 * 		AnnotationAwareAspectJAutoProxyCreator
 * 			->AspectJAwareAdvisorAutoProxyCreator
 * 				->AbstractAdvisorAutoProxyCreator
 * 					->AbstractAutoProxyCreator
 * 							implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
 * 						关注后置处理器(在bean初始化完成前后做事情)、自动装配BeanFactory
 * 
 * AbstractAutoProxyCreator.setBeanFactory()
 * AbstractAutoProxyCreator.有后置处理器的逻辑;
 * 
 * AbstractAdvisorAutoProxyCreator.setBeanFactory()-》initBeanFactory()
 * 
 * AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()
 *
 *
 * 流程:
 * 		1)、传入配置类,创建ioc容器
 * 		2)、注册配置类,调用refresh()刷新容器;
 * 		3)、registerBeanPostProcessors(beanFactory);注册bean的后置处理器来方便拦截bean的创建;
 * 			1)、先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor
 * 			2)、给容器中加别的BeanPostProcessor
 * 			3)、优先注册实现了PriorityOrdered接口的BeanPostProcessor;
 * 			4)、再给容器中注册实现了Ordered接口的BeanPostProcessor;
 * 			5)、注册没实现优先级接口的BeanPostProcessor;
 * 			6)、注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中;
 * 				创建internalAutoProxyCreator的BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】
 * 				1)、创建Bean的实例
 * 				2)、populateBean;给bean的各种属性赋值
 * 				3)、initializeBean:初始化bean;
 * 						1)、invokeAwareMethods():处理Aware接口的方法回调
 * 						2)、applyBeanPostProcessorsBeforeInitialization():
                                          应用后置处理器的postProcessBeforeInitialization()
 * 						3)、invokeInitMethods();执行自定义的初始化方法
 * 						4)、applyBeanPostProcessorsAfterInitialization();
                                          执行后置处理器的postProcessAfterInitialization();
 * 				4)、BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)
                                          创建成功;--》aspectJAdvisorsBuilder
 * 			7)、把BeanPostProcessor注册到BeanFactory中;
 * 				beanFactory.addBeanPostProcessor(postProcessor);
 * =======以上是创建和注册AnnotationAwareAspectJAutoProxyCreator的过程========
 * 
 * 			AnnotationAwareAspectJAutoProxyCreator => InstantiationAwareBeanPostProcessor
 * 		4)、finishBeanFactoryInitialization(beanFactory);完成BeanFactory初始化工作;创建剩下的单实例bean
 * 			1)、遍历获取容器中所有的Bean,依次创建对象getBean(beanName);
 * 				getBean->doGetBean()->getSingleton()->
 * 			2)、创建bean
 * 				【AnnotationAwareAspectJAutoProxyCreator在所有bean创建之前会有一个拦截,
                           InstantiationAwareBeanPostProcessor,会调用postProcessBeforeInstantiation()】
 * 				1)、先从缓存中获取当前bean,如果能获取到,说明bean是之前被创建过的,直接使用,否则再创建;
 * 					只要创建好的Bean都会被缓存起来
 * 				2)、createBean();创建bean;
 * 					AnnotationAwareAspectJAutoProxyCreator 会在任何bean创建之前先尝试返回bean的实例
 * 					【BeanPostProcessor是在Bean对象创建完成初始化前后调用的】
 * 					【InstantiationAwareBeanPostProcessor是在创建Bean实例之前先尝试用后置处理器返回对象的】
 * 					1)、resolveBeforeInstantiation(beanName, mbdToUse);解析BeforeInstantiation
 * 						希望后置处理器在此能返回一个代理对象;如果能返回代理对象就使用,如果不能就继续
 * 						1)、后置处理器先尝试返回对象;
 * 							bean = applyBeanPostProcessorsBeforeInstantiation():
 * 								拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor;
 * 								就执行postProcessBeforeInstantiation
 * 							if (bean != null) {
								bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
							}
 * 
 * 					2)、doCreateBean(beanName, mbdToUse, args);真正的去创建一个bean实例;和3.6流程一样;
 * 					3)、
 * 			
 * 		
 * AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】	的作用:
 * 1)、每一个bean创建之前,调用postProcessBeforeInstantiation();
 * 		关心MathCalculator和LogAspect的创建
 * 		1)、判断当前bean是否在advisedBeans中(保存了所有需要增强bean)
 * 		2)、判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean,
 * 			或者是否是切面(@Aspect)
 * 		3)、是否需要跳过
 * 			1)、获取候选的增强器(切面里面的通知方法)【List<Advisor> candidateAdvisors】
 * 				每一个封装的通知方法的增强器是 InstantiationModelAwarePointcutAdvisor;
 * 				判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;返回true
 * 			2)、永远返回false
 * 
 * 2)、创建对象
 * postProcessAfterInitialization;
 * 		return wrapIfNecessary(bean, beanName, cacheKey);//包装如果需要的情况下
 * 		1)、获取当前bean的所有增强器(通知方法)  Object[]  specificInterceptors
 * 			1、找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的)
 * 			2、获取到能在bean使用的增强器。
 * 			3、给增强器排序
 * 		2)、保存当前bean在advisedBeans中;
 * 		3)、如果当前bean需要增强,创建当前bean的代理对象;
 * 			1)、获取所有增强器(通知方法)
 * 			2)、保存到proxyFactory
 * 			3)、创建代理对象:Spring自动决定
 * 				JdkDynamicAopProxy(config);jdk动态代理;
 * 				ObjenesisCglibAopProxy(config);cglib的动态代理;
 * 		4)、给容器中返回当前组件使用cglib增强了的代理对象;
 * 		5)、以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程;
 * 		
 * 	
 * 	3)、目标方法执行	;
 * 		容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,xxx);
 * 		1)、CglibAopProxy.intercept();拦截目标方法的执行
 * 		2)、根据ProxyFactory对象获取将要执行的目标方法拦截器链;
 * 			List<Object> chain = 
                       this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
 * 			1)、List<Object> interceptorList保存所有拦截器 5
 * 				一个默认的ExposeInvocationInterceptor 和 4个增强器;
 * 			2)、遍历所有的增强器,将其转为Interceptor;
 * 				registry.getInterceptors(advisor);
 * 			3)、将增强器转为List<MethodInterceptor>;
 * 				如果是MethodInterceptor,直接加入到集合中
 * 				如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor;
 * 				转换完成返回MethodInterceptor数组;
 * 
 * 		3)、如果没有拦截器链,直接执行目标方法;
 * 			拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)
 * 		4)、如果有拦截器链,把需要执行的目标对象,目标方法,
 * 			拦截器链等信息传入创建一个 CglibMethodInvocation 对象,
 * 			并调用 Object retVal =  mi.proceed();
 * 		5)、拦截器链的触发过程;
 * 			1)、如果没有拦截器执行执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)
                执行目标方法;
 * 			2)、链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;
 * 				拦截器链的机制,保证通知方法与目标方法的执行顺序;
 * 		
 * 	总结:
 * 		1)、  @EnableAspectJAutoProxy 开启AOP功能
 * 		2)、 @EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator
 * 		3)、AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
 * 		4)、容器的创建流程:
 * 			1)、registerBeanPostProcessors()注册后置处理器;
                                              创建AnnotationAwareAspectJAutoProxyCreator对象
 * 			2)、finishBeanFactoryInitialization()初始化剩下的单实例bean
 * 				1)、创建业务逻辑组件和切面组件
 * 				2)、AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
 * 				3)、组件创建完之后,判断组件是否需要增强
 * 					是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib);
 * 		5)、执行目标方法:
 * 			1)、代理对象执行目标方法
 * 			2)、CglibAopProxy.intercept();
 * 				1)、得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
 * 				2)、利用拦截器的链式机制,依次进入每一个拦截器进行执行;
 * 				3)、效果:
 * 					正常执行:前置通知-》目标方法-》后置通知-》返回通知
 * 					出现异常:前置通知-》目标方法-》后置通知-》异常通知
 * 		
 * 
 * 
 */

2.源码分析

要真正了解spring中的aop,必须先清除spring中的ioc原理。ioc是spring实现aop的基础。其次是了解两种动态代理的机制,一个是jdk动态代理,一个是cglib动态代理。

@EnableAspectJAutoProxy

首先就从==@EnableAspectJAutoProxy==这个注解开始,我们看下这个注解的源码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	/**
	 * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
	 * to standard Java interface-based proxies. The default is {@code false}.
	 */
	boolean proxyTargetClass() default false;

	/**
	 * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
	 * for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
	 * Off by default, i.e. no guarantees that {@code AopContext} access will work.
	 * @since 4.3.1
	 */
	boolean exposeProxy() default false;

}

这个注解使用了@Import注解机制,用于向spring容器中导入组件,并且把注解里面的两个属性可以设置到这个组件中。

AspectJAutoProxyRegistrar

我们还是来看下导入了什么组件?下面调用了一个静态方法,往spring容器中注入组件。

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

    /**
    * Register, escalate, and configure the AspectJ auto proxy creator based on the value
    * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
    * {@code @Configuration} class.
    */
    @Override
    public void registerBeanDefinitions(
        AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		
		// 使用AOPConfigUtils往spring容器中注入创建AOP代理的后置处理器
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

        // 如果@EnableAspectJAutoProxy这个注解,有标注@EnableAspectJAutoProxy这个注解,
        // 那么把AOP代理的后置处理器的这两个属性都设置成标注的值
        AnnotationAttributes enableAspectJAutoProxy =
            AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
        }
        if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
            AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
        }
    }

}

AopConfigUtils

那么先来看下AOPConfigUtils是怎么注入这个AOP代理的后置处理器的,

public abstract class AopConfigUtils {

    /**
	 * The bean name of the internally managed auto-proxy creator.
	 */
    // 注入到spring容器中创建AOP代理后置处理器的名字,后面将直接根据名字来拿,这个名字是写死的
    public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
        "org.springframework.aop.config.internalAutoProxyCreator";

    /**
	 * Stores the auto proxy creator classes in escalation order.
	 */
    private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<Class<?>>();
    
    /**
	 * 自动代理创建器的列表, 从上到下, 下面的将会优先选择, 这个可以在下面的代码里面看到
	 */
	static {
		APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
		APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
		APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
	}
    
    // 注入的组件里面,调用下面这个方法
    public static BeanDefinition 
        registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) 
    {
        return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
    }
    
    // 这里直接写死注入的后置处理器【AnnotationAwareAspectJAutoProxyCreator.class】
    public static BeanDefinition 
        registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, 
                                                             Object source) 
    {
        return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, 
                                               registry, 
                                               source);
    }
    
    private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, 
                                                                  BeanDefinitionRegistry registry,
                                                                  Object source) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        
        // 看容器中是否有名字叫做"org.springframework.aop.config.internalAutoProxyCreator"的bean定义信息
        if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
            // 如果有,就拿到它
            BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
            // 如果传过来的class,和容器中的这个组件的类不是同一个,那么就比较它们的优先级, 设置为优先级高的
            //                 上面保存了一个列表,这样优先级也好比,谁在后面谁的优先级越大
            if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
                int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
                int requiredPriority = findPriorityForClass(cls);
                if (currentPriority < requiredPriority) {
                    apcDefinition.setBeanClassName(cls.getName());
                }
            }
            return null;
        }
        // 如果容器里面没有,那么就直接设置传过来的【AnnotationAwareAspectJAutoProxyCreator】
        RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
        beanDefinition.setSource(source);
        // 我们可以学习一下这种用法,使用beanDefinition设值,这里默认设置了最高优先级(如果容器之前没有配置该组件)
        beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
        // 标记为框架级别的角色(ROLE_INFRASTRUCTURE)
        //     还有另外两种:框架支持的角色(ROLE_SUPPORT)、应用级别的角色(ROLE_APPLICATION)
        beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        // 好的,注册到spring容器当中
        registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
        return beanDefinition;
    }
    
    // 比较优先级的代码,返回类在列表里的索引
    private static int findPriorityForClass(String className) {
		for (int i = 0; i < APC_PRIORITY_LIST.size(); i++) {
			Class<?> clazz = APC_PRIORITY_LIST.get(i);
			if (clazz.getName().equals(className)) {
				return i;
			}
		}
		throw new IllegalArgumentException(
				"Class name [" + className + "] is not a known auto-proxy creator class");
	}
    
}

好的,经过上面的对@EnableAspectJAutoProxy注解的解析,我们引入了主角==AnnotationAwareAspectJAutoProxyCreator==

AnnotationAwareAspectJAutoProxyCreator

从名字也可以看出它是支持AspectJ注解驱动的自动代理创建器,我们先看看它的继承树,从而了解它的家族体系。

AbstractAutoProxyCreator

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vGRaI0hU-1623858305944)(assets/image-20210614204838694.png)]

从图中可以看出如下几点:

自动代理创建器是从**AbstractAutoProxyCreator**开始的,它下面有两个分支,一个是【BeanNameAutoProxyCreator】以BeanName来指定哪些名字的bean需要被代理(同时设置interceptorNames标识哪些名字的bean作为切面),一个是【AbstractAutoProxyCreator】以指定切面(切点+增强),即【advisor = advice + pointcut】的方式去横向的指定一批满足切点条件的bean,创建它们的代理,并将增强织入进去。

AbstractAutoProxyCreator实现了BeanPostProcessor接口,说明它具有后置处理器的功能,并且它将在bean的实例化和初始化的时候做出相应的拦截。还实现了BeanFactoryAware几口,说明它会保存beanFactory工厂,那么它就能拿到bean工厂中的所有bean信息,这两个接口是它将AOP功能整合到spring容器的关键接口,这也说明如果我们要自定义扩展也可以这么去做!

AbstractAutoProxyCreator继承了ProxyConfig类,而ProxyConfig类种定义了与创建动态代理配置相关的信息,我们先简单的看下这个类,那么为什么要继承自这个类呢?因为自动代理创建器是使用ProxyFactory去创建代理的,而ProxyFactory不是面向用户使用的,ProxyFactory也继承自这个类,那么有些配置信息需要用户通过自动代理创建器的配置来指定,然后传递(拷贝)给ProxyFactory,那么创建代理的时候就可以应用这些配置了。

public class ProxyConfig implements Serializable {

    private static final long serialVersionUID = -8409359707199703185L;

    private boolean proxyTargetClass = false;

    private boolean optimize = false;

    boolean opaque = false;

    boolean exposeProxy = false;

    private boolean frozen = false;
    
    // 省略其它方法
    public void copyFrom(ProxyConfig other) {
        Assert.notNull(other, "Other ProxyConfig object must not be null");
        this.proxyTargetClass = other.proxyTargetClass;
        this.optimize = other.optimize;
        this.exposeProxy = other.exposeProxy;
        this.frozen = other.frozen;
        this.opaque = other.opaque;
    }
    ...
}

下图,我们可以看到自动代理创建器,是继承了ProxyConfig。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T3QdfOGt-1623858305946)(assets/image-20210614212130692.png)]

上面我们简单的分析了一下这个类,下面我们再详细的看下这个类中定义的方法。

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
    implements SmartInstantiationAwareBeanPostProcessor, 
BeanFactoryAware {

    // 方便使用, 标识不用创建代理
    protected static final Object[] DO_NOT_PROXY = null;

    // 方便使用,标识不用附加拦截器
    protected static final Object[] PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS = new Object[0];

    // 切面适配器注册中心,因为有些切面(advisor)返回的增强(advice)并没有实现MethodInterceptor接口,
    //                  在后面调用的时候都会统一适配成MethodInterceptor接口来调用。                               // 这里返回的是个固定的对象【DefaultAdvisorAdapterRegistry】
    //                  它里面默认就注册了MethodBeforeAdviceAdapter、                                         //                                 AfterReturningAdviceAdapter、
    //                                 ThrowsAdviceAdapter           
    private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();

    
    private boolean freezeProxy = false;

    // 默认没有拦截器,这里的拦截器是bean的名字
    /** Default is no common interceptors */
    private String[] interceptorNames = new String[0];

    // 是否要把公共的拦截器放到最前面
    private boolean applyCommonInterceptorsFirst = true;

    // 目标对象创建器
    private TargetSourceCreator[] customTargetSourceCreators;

    // 【保存的bean工厂】
    private BeanFactory beanFactory;

    // 被customTargetSourceCreators创建过TargetSource的beanName的集合
    private final Set<String> targetSourcedBeans =
        Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));

    // 与循环依赖有关
    private final Set<Object> earlyProxyReferences =
        Collections.newSetFromMap(new ConcurrentHashMap<Object, Boolean>(16));

    // 创建代理后,会保存cacheKey和proxy.getClass到proxyTypes中
    private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<Object, Class<?>>(16);

    // 用于记录bean是否应该被代理,key是cacheKey,value表示是/否
    private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<Object, Boolean>(256);


    // 设定是否冻结
    @Override
    public void setFrozen(boolean frozen) {
        this.freezeProxy = frozen;
    }

    @Override
    public boolean isFrozen() {
        return this.freezeProxy;
    }

    // 设置切面适配器,将Object类型的advice适配MethodInterceptor接口
    public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) {
        this.advisorAdapterRegistry = advisorAdapterRegistry;
    }

    // 用来在postProcessorBeforeInstantiation根据beanClass&beanName创建TargetSource
    public void setCustomTargetSourceCreators(TargetSourceCreator... targetSourceCreators) {
        this.customTargetSourceCreators = targetSourceCreators;
    }

    // 设置拦截器的名字,即根据interceptorNames到beanFactory中查找切面
    public void setInterceptorNames(String... interceptorNames) {
        this.interceptorNames = interceptorNames;
    }

    /**
	 * Set whether the common interceptors should be applied before bean-specific ones.
	 * Default is "true"; else, bean-specific interceptors will get applied first.
	 */
    public void setApplyCommonInterceptorsFirst(boolean applyCommonInterceptorsFirst) {
        this.applyCommonInterceptorsFirst = applyCommonInterceptorsFirst;
    }

    // 子类有重写这个方法,并且把beanFactory保存下来,封装到一个对象里面,用以查找切面
    // 比如子类:AbstractAdvisorAutoProxyCreator
    //                   BeanFactoryAdvisorRetrievalHelperAdapter
    //                                  ->能用来找容器中的实现了Advisor的bean
    //    子类:AnnotationAwareAspectJAutoProxyCreator
    //                   BeanFactoryAspectJAdvisorsBuilderAdapter
    //                                   ->借助AspectJAdvisorFactory通过@Aspect注解来找
    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    // 代理对象一旦被创建,将会保存它的类型到proxyTypes中,这里通过cacheKey,获取代理对象的所属class类
    @Override
    public Class<?> predictBeanType(Class<?> beanClass, String beanName) {
        if (this.proxyTypes.isEmpty()) {
            return null;
        }
        Object cacheKey = getCacheKey(beanClass, beanName);
        return this.proxyTypes.get(cacheKey);
    }

    // 不提供确定构造器的功能
    @Override
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) 
        return null;
    }

	// 如果这个方法被调用,证明ioc容器中遇到了循环依赖的情况,
    // wrapIfNecessary用于创建代理的逻辑(当然包括是否应该要创建代理的逻辑,下面详细说)
    @Override
    public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        // 如果之前没有添加,那么把它添加进去。标记这个bean&beanName已经走过创建代理的逻辑了,
        // 那么在下面postProcessAfterInitialization的过程中,发现已经存到了earlyProxyReferences
        // 那么就不要再走一遍wrapIfNecessary创建代理的逻辑,
        // 因为这个wrapIfNecessary只应该走一遍,而且代理早就暴露出去了(与循环依赖相关)
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            this.earlyProxyReferences.add(cacheKey);
        }
        return wrapIfNecessary(bean, beanName, cacheKey);
    }

	// 在doCreateBean之前的一个回调,如果能返回,那么就不会走创建bean的逻辑了
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 
                                                                            throws BeansException {
        Object cacheKey = getCacheKey(beanClass, beanName);

        // 如果targetSourceBeans里面没有这个beanName
        // (如果里面有,那就说明该方法以前处理过,也说明能返回结果,那就不用下面的判断了)
        if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
            
            // 如果advisedBeans有这个cacheKey,就返回一个null
            // (那就说面下面这个判断的逻辑已经走过了,没必要再走,直接返回)
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            
            // 如果是框架里面的类:
            //             【Advice、Pointcut、Advisor、AopInfrastructureBean】
            
            // 或者是应该跳过(shouldSkip方法在本类中默认返回false,意为都不应该被跳过)
            //             AspectJAwareAdvisorAutoProxyCreator重写了该方法,逻辑是切面类应该被跳过
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                // 在advisedBeans中标记一下这个cachekey为false
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }

       
        if (beanName != null) {
            
            // 遍历本类的customTargetSourceCreators属性,然后根据beanClass和beanName返回TargetSource
            // (先返回原则)
            TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
            
            // 如果有返回,
            if (targetSource != null) {
                // 那就把beanName添加到targetSourceBeans集合里面去
                this.targetSourcedBeans.add(beanName);
                
                // 为当前的这个beanClass类,目标对象targetSource查找增强器和切面(也就是拦截器)
                // 这是个模板方法,由子类实现
                Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, 
                                                                             beanName, 
                                                                             targetSource);
                // 获取到拦截器后,就可以创建代理了,使用ProxyFactory创建代理
                Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
                
                // 保存创建的代理对象的类到proxyTypes
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            }
        }

        return null;
    }

	// 一般是在这个方法里创建的代理
    /**
	 * Create a proxy with the configured interceptors if the bean is
	 * identified as one to proxy by the subclass.
	 * @see #getAdvicesAndAdvisorsForBean
	 */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 如果bean不为空
        if (bean != null) {
            // 创建缓存cacheKey
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            
            // 如果earlyProxyReferences集合中没有包含cacheKey,才会走wrapIfNecessary创建代理的逻辑
            // 言外之意就是: 如果这个bean,被提前暴露了,那么无论它是否被代理,都走直接返回。
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }

	// 如果有beanName,那么优先用beanName,并且如果是FactoryBean,那么加上&
	// 否则就用beanClass了
    protected Object getCacheKey(Class<?> beanClass, String beanName) {
        if (StringUtils.hasLength(beanName)) {
            return (FactoryBean.class.isAssignableFrom(beanClass) ?
                    BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
        }
        else {
            return beanClass;
        }
    }

    // 返回原始bean或者返回代理
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        
        // postPrcessBeforeInstantiation的逻辑有创建代理,这里就直接返回
        if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        
        // 从advisedBeans里面,根据cacheKey的标记为false的就不做代理了
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        
        // 如果是框架里面的类:
        //             【Advice、Pointcut、Advisor、AopInfrastructureBean】

        // 或者是应该跳过(shouldSkip方法在本类中默认返回false,意为都不应该被跳过)
        //             AspectJAwareAdvisorAutoProxyCreator重写了该方法,逻辑是切面类应该被跳过
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            // 在advisedBeans中标记一下这个cachekey为false
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
		
        // 根据beanClass和beanName查看拦截器(切面),这是个模板方法,由子类去实现
        // Create proxy if we have advice.
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        
        // 如果拦截器不为null,那就做代理;如果为null,那就不做代理,然后使用advisedBeans标记一下这个cacheKey
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            Object proxy = createProxy( bean.getClass(), beanName,       // 目标对象&beanName
                                       specificInterceptors,             // 拦截器
                                       new SingletonTargetSource(bean)); // 包装bean
            
            // 创建代理后,就放入proxyTypes记录下cacheKey和代理类的class
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }

        // 只要经过wrapIfNecessary这个流程,那么就相当于在advisedBeans标记了这个bean
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

	// 【框架里面的特定类】和【满足shouldSkip的bean】应该要跳过
    protected boolean isInfrastructureClass(Class<?> beanClass) {
        boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
            Pointcut.class.isAssignableFrom(beanClass) ||
                Advisor.class.isAssignableFrom(beanClass) ||
                    AopInfrastructureBean.class.isAssignableFrom(beanClass);
        if (retVal && logger.isTraceEnabled()) {
            logger.trace("Did not attempt to auto-proxy infrastructure class [" 
                         + beanClass.getName() + "]");
        }
        return retVal;
    }

    // 这里默认所有的bean都不应该被跳过,子类有重写shouldKip方法
	// 比如子类AspectJAwareAdvisorAutoProxyCreator重写逻辑:所有的切面名字的bean都跳过
    protected boolean shouldSkip(Class<?> beanClass, String beanName) {
        return false;
    }

    // 遍历customTargetSourceCreators来为当前的beanClass&beanName 创建TargetSource
    protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) {
        // We can't create fancy target sources for directly registered singletons.
        if (this.customTargetSourceCreators != null &&this.beanFactory != null 
                                                    && this.beanFactory.containsBean(beanName)) {
            for (TargetSourceCreator tsc : this.customTargetSourceCreators) {
                TargetSource ts = tsc.getTargetSource(beanClass, beanName);
                if (ts != null) {
                    // Found a matching TargetSource.
                    if (logger.isDebugEnabled()) {
                        logger.debug("TargetSourceCreator [" + tsc +
                                     " found custom TargetSource for bean with name '" 
                                     + beanName + "'");
                    }
                    return ts;
                }
            }
        }
        
        // 如果没有customTargetSourceCreators,就返回null
        // No custom TargetSource found.
        return null;
    }

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

        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            // 从beanFactory中根据beanName拿到beanDefinition,
            // 然以AutoProxyUtils#ORIGINAL_TARGET_CLASS_ATTRIBUTE保存beanClass到beanDefinition属性里去
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, 
                                             beanName, beanClass);
        }

        // 我们知道ProxyFactory也继承了ProxyConfig,所以下面即拷贝了当前后置处理器的属性了
        //                          属性有:【proxyTargetClass、optimize、exposeProxy、frozen、opaque】
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);

        // 如果后置处理器的proxyTargetClass属性为false,那就代表使用jdk动态代理,
        //                          而jdk动态代理是只能代理接口,是有条件限制的
        if (!proxyFactory.isProxyTargetClass()) {
            // 如果ProxyTargetClass设置为false,那么从bean工厂里面拿到beanName的beanDefinition,
            //                                里面有个属性AutoProxyUtils#PRESERVE_TARGET_CLASS_ATTRIBUTE
            //                                如果这个属性为true,那就返回true,否则返回false
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                // 这个就是在搜集beanClass的所有接口,并且不包括InitializingBean、DisposableBean、Closeable等等
                // 并且接口里面的方法个数要>0,然后把这些接口添加到proxyFactory中,
                // 否则,还是设置proxyFactory的proxyTargetClass属性为true
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }

        // 将所有的拦截器都适配成切面Advisor接口,适配使用的就是DefaultAdvisorAdapterRegistry对象
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
        
        // 设置目标对象
        proxyFactory.setTargetSource(targetSource);
        
        // 模板方法,由子类扩展..可在此做修改
        customizeProxyFactory(proxyFactory);
		
        // 设置frozen属性,当配置被冻结了,那么就不能修改增强了
        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            // 后面有用到这个开关,当前类返回false,子类AbstractAdvisorAutoProxyCreator重写为true
            proxyFactory.setPreFiltered(true);
        }

        // 使用proxyFactory获取代理对象
        return proxyFactory.getProxy(getProxyClassLoader());
    }


    // 那么从bean工厂里面拿到beanName的beanDefinition,
    //               beanDefinition里面有个属性AutoProxyUtils#PRESERVE_TARGET_CLASS_ATTRIBUTE
    //               如果这个属性为true,那就返回true,否则返回false
    // 这里就是看beanDefinition信息,我们可以设定这个值,强制使用cglib
    protected boolean shouldProxyTargetClass(Class<?> beanClass, String beanName) {
        return (this.beanFactory instanceof ConfigurableListableBeanFactory &&
                AutoProxyUtils
                .shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName));
    }

    // 子类返回的切面是不是都对目标对象的类判断过了,那么ClassFilter的判断就可以跳过了
    protected boolean advisorsPreFiltered() {
        return false;
    }

    
	// 对给定的bean和Object类型的拦截器和interceptorNames 
    // 通过本类的DefaultAdvisorAdapterRegistry属性都适配成Advisor接口类型,如果适配失败将会抛出异常
    protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {
        
        // 根据interceptorNames到容器中找bean,适配成Advisor接口,所以interceptorNames不能乱写
        Advisor[] commonInterceptors = resolveInterceptorNames();

        List<Object> allInterceptors = new ArrayList<Object>();
        
        if (specificInterceptors != null) {
            allInterceptors.addAll(Arrays.asList(specificInterceptors));
            if (commonInterceptors.length > 0) {
                if (this.applyCommonInterceptorsFirst) {
                    allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
                }
                else {
                    allInterceptors.addAll(Arrays.asList(commonInterceptors));
                }
            }
        }

        Advisor[] advisors = new Advisor[allInterceptors.size()];
        for (int i = 0; i < allInterceptors.size(); i++) {
            advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
        }
        return advisors;
    }

    private Advisor[] resolveInterceptorNames() {
        ConfigurableBeanFactory cbf = (this.beanFactory instanceof ConfigurableBeanFactory ?
                                       (ConfigurableBeanFactory) this.beanFactory : null);
        List<Advisor> advisors = new ArrayList<Advisor>();
        for (String beanName : this.interceptorNames) {
            if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) {
                Object next = this.beanFactory.getBean(beanName);
                advisors.add(this.advisorAdapterRegistry.wrap(next));
            }
        }
        return advisors.toArray(new Advisor[advisors.size()]);
    }

    // 允许子类修改proxyFactory的设置,执行时机是在 暴露接口/添加Advisors之后,
    protected void customizeProxyFactory(ProxyFactory proxyFactory) {
    }


    // 这是个模板方法,由子类返回当前bean的所有拦截器,但必须能够使用DefaultAdvisorAdapterRegistry作适配
    protected abstract Object[] getAdvicesAndAdvisorsForBean(
        Class<?> beanClass, String beanName, TargetSource customTargetSource) throws BeansException;

}

AbstractAutoProxyCreator类大概作的事情如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3OcxUlUt-1623858305947)(assets/image-20210615084602366.png)]

所以接下来的分析,将会是子类为当前bean查找拦截器的逻辑使用proxyFactory获取代理的逻辑

AbstractAdvisorAutoProxyCreator

我们先看第一个子类为当前bean查找拦截器的逻辑,我们来到直接子类AbstractAdvisorAutoProxyCreator,这个类里面的方法都是查找获取切面相关的方法。

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {

    // 实现类为BeanFactoryAdvisorRetrievalHelperAdapter,它继承了BeanFactoryAdvisorRetrievalHelper
    //                                                 意为从beanFactory中查找切面
    // 其实找的就是实现了Advisor接口的bean,然后判断每个Advisor接口的bean是否有资格(isEligible)
    //                                  这里的适配器就重写了isEligibleAdvisorBean逻辑,排除掉一些切面
    private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;


    // 重写了setBeanFactory方法
    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        super.setBeanFactory(beanFactory);
        if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
            throw new IllegalArgumentException(
                "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
        }
        initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
    }

    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 直接new的BeanFactoryAdvisorRetrievalHelperAdapter,这个类为内部类,
        //     只重写了isEligibleAdvisorBean逻辑,将这部分判断逻辑转移到本类及子类中
        this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
    }


    @Override
    protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, 
                                                    TargetSource targetSource) {

        // 查找所有的Advisor,并从所有的Advisor中筛选出找到满足条件的
        List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);

        if (advisors.isEmpty()) {
            // 没有找到,则返回null
            return DO_NOT_PROXY;
        }

        return advisors.toArray();
    }


    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        // 查找所有候选的advisor切面
        //        子类AnnotationAwareAspectJAutoProxyCreator重写了,除了调用父类方法,还从spring容器中
        //        找到所有的bean,并且根据@Aspect注解来找所有的bean,然后提取信息,创建为切面,添加进来
        List<Advisor> candidateAdvisors = findCandidateAdvisors();

        // 从候选的advisor中筛选出能应用到目标对象的切面
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, 
                                                                  beanClass, beanName);
        // 模板方法,筛选完之后,让子类还能继续增删改advisor
        //         子类AspectJAwareAdvisorAutoProxyCreator
        //                使用AspectJProxyUtils#makeAdvisorChainAspectJCapableIfNecessary方法
        //                往eligibleAdvisors里面的起始位置还添加了ExposeInvocationInterceptor.ADVISOR 
        //                (用于暴露当前的MethodInvocation)
        extendAdvisors(eligibleAdvisors);

        if (!eligibleAdvisors.isEmpty()) {
            // 给所有的切面排序
            //     本类使用spring常用的@Order注解或者Ordered接口排序
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }

    // 借助BeanFactoryAdvisorRetrievalHelperAdapter从beanFactory中找到候选的advisor,
    //    就是根据Advisor接口来找
    protected List<Advisor> findCandidateAdvisors() {
        return this.advisorRetrievalHelper.findAdvisorBeans();
    }

    // 使用工具类AopUtils从所有的候选切面中找到能应用到当前bean的切面,后面单独看
    protected List<Advisor> findAdvisorsThatCanApply(
        List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

        ProxyCreationContext.setCurrentProxiedBeanName(beanName);
        try {
            return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
        }
        finally {
            ProxyCreationContext.setCurrentProxiedBeanName(null);
        }
    }

    // 默认都是true,即所有的bean都满足
    //             这个方法有被BeanFactoryAdvisorRetrievalHelperAdapter用到,使用外部类的逻辑来实现
    //             这里用法很妙有木有?内部类继承另外的类,然后使用外部类的方法去改写另外的类的部分逻辑
    //                              然后外部类组合内部类。
    protected boolean isEligibleAdvisorBean(String beanName) {
        return true;
    }

    // 对切面进行排序
    protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
        AnnotationAwareOrderComparator.sort(advisors);
        return advisors;
    }

    // 模板方法,子类可以继续添加切面
    protected void extendAdvisors(List<Advisor> candidateAdvisors) {
    }

   	// 重写了父类的方法(父类默认返回false),这里的意思是所有的advisors都对当前的bean预过滤了
    @Override
    protected boolean advisorsPreFiltered() {
        return true;
    }


    /**
    * Subclass of BeanFactoryAdvisorRetrievalHelper that delegates to
    * surrounding AbstractAdvisorAutoProxyCreator facilities.
    */
    private class BeanFactoryAdvisorRetrievalHelperAdapter extends BeanFactoryAdvisorRetrievalHelper {

        public BeanFactoryAdvisorRetrievalHelperAdapter(ConfigurableListableBeanFactory beanFactory) {
            // 把beanFactory工厂传过去
            super(beanFactory);
        }

        @Override
        protected boolean isEligibleBean(String beanName) {
            // 使用外部类的isEligibleAdvisorBean方法改写逻辑
            return AbstractAdvisorAutoProxyCreator.this.isEligibleAdvisorBean(beanName);
        }
    }

}

这个类大概做的功能就是这些

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t7stBq1A-1623858305949)(assets/image-20210615100346452.png)]

BeanFactoryAdvisorRetrievalHelper

看看AbstractAdvisorAutoProxyCreator类中借助BeanFactoryAdvisorRetrievalHelper如何查找切面的,

public class BeanFactoryAdvisorRetrievalHelper {

    private static final Log logger = LogFactory.getLog(BeanFactoryAdvisorRetrievalHelper.class);

    // beanFactory工厂
    private final ConfigurableListableBeanFactory beanFactory;

    // 找到的切面缓存起来
    private String[] cachedAdvisorBeanNames;


    // beanFactory必传,且不能为null
    public BeanFactoryAdvisorRetrievalHelper(ConfigurableListableBeanFactory beanFactory) {
        Assert.notNull(beanFactory, "ListableBeanFactory must not be null");
        this.beanFactory = beanFactory;
    }

	// 从beanFactory中查找所有的Advisor的bean
    public List<Advisor> findAdvisorBeans() {
        // Determine list of advisor bean names, if not cached already.
        String[] advisorNames = null;
        synchronized (this) {
            advisorNames = this.cachedAdvisorBeanNames;
            if (advisorNames == null) {
                
                // 这里直接找【Advisor.class】的bean,
                //    而且我们还看到了,为了防止FactoryBean初始化,特定使用了beanNamesForTypeIncludingAncestors
                //    下次我们也这样用
                
                // Do not initialize FactoryBeans here: We need to leave all regular beans
                // uninitialized to let the auto-proxy creator apply to them!
                advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                    this.beanFactory, Advisor.class, true, false);
                this.cachedAdvisorBeanNames = advisorNames;
            }
        }
        if (advisorNames.length == 0) {
            return new LinkedList<Advisor>();
        }

        List<Advisor> advisors = new LinkedList<Advisor>();
        
        // 根据获取到的Advisor的beanName名字,从容器中拿到所有的切面
        for (String name : advisorNames) {
            if (isEligibleBean(name)) {
                if (this.beanFactory.isCurrentlyInCreation(name)) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Skipping currently created advisor '" + name + "'");
                    }
                }
                else {
                    try {
                        advisors.add(this.beanFactory.getBean(name, Advisor.class));
                    }
                    catch (BeanCreationException ex) {
                        Throwable rootCause = ex.getMostSpecificCause();
                        if (rootCause instanceof BeanCurrentlyInCreationException) {
                            BeanCreationException bce = (BeanCreationException) rootCause;
                            if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {
                                if (logger.isDebugEnabled()) {
                                    logger.debug("Skipping advisor '" + name +
                                                 "' with dependency on currently created bean: "
                                                 + ex.getMessage());
                                }                    
                                continue;
                            }
                        }
                        throw ex;
                    }
                }
            }
        }
        return advisors;
    }

    // 这个方法被AbstractAdvisorAutoProxyCreator中的内部类BeanFactoryAdvisorRetrievalHelperAdapter重写了
    protected boolean isEligibleBean(String beanName) {
        return true;
    }

}

AopUtils.findAdvisorsThatCanApply

看看工具类中是如何筛选切面

public abstract class AopUtils {

    public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, 
                                                         Class<?> clazz) {
        // 是空的,原样返回
        if (candidateAdvisors.isEmpty()) {
            return candidateAdvisors;
        }

        List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();

        // 判断里面有没有IntroductionAdvisor的切面,并且看这个切面能不能应用到beanClass
        //            IntroductionAdvisor接口切面的粒度是类级别的,里面只有ClassFilter用来过滤类
        for (Advisor candidate : candidateAdvisors) {
            // 调用canApply(candidate, clazz, false)
            if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                // 如果能应用到beanClass就添加到eligibleAdvisors
                eligibleAdvisors.add(candidate);
            }
        }

        // 说明有引介切面
        boolean hasIntroductions = !eligibleAdvisors.isEmpty();

        for (Advisor candidate : candidateAdvisors) {

            if (candidate instanceof IntroductionAdvisor) {
                // 前面已经处理过了IntroductionAdvisor
                // already processed
                continue;
            }

            // 将能应用的切面添加到eligibleAdvisors中,那么就先看看canApply(Advisor, Class<?>, boolean)方法
            if (canApply(candidate, clazz, hasIntroductions)) {
                eligibleAdvisors.add(candidate);
            }
        }
        return eligibleAdvisors;
    }

    public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
        // 如果是引介切面,那么就直接用ClassFilter来判断targetClass
        if (advisor instanceof IntroductionAdvisor) {
            return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
        }
        // 如果是PointcutAdvisor,那么就使用Pointcut切点来判断targetClass
        else if (advisor instanceof PointcutAdvisor) {
            PointcutAdvisor pca = (PointcutAdvisor) advisor;
            // 使用切点来做判断,第三个参数表示是否存在引介切面
            return canApply(pca.getPointcut(), targetClass, hasIntroductions);
        }
        else {
            // It doesn't have a pointcut so we assume it applies.
            return true;
        }
    }

    public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
        Assert.notNull(pc, "Pointcut must not be null");
        
        // Pointcut中定义了ClassFilter和MethodMatcher,粒度是方法级别
        
        // 如果没有匹配到该类,那么返会false
        if (!pc.getClassFilter().matches(targetClass)) {
            return false;
        }
		
        // 然后用方法去做匹配
        MethodMatcher methodMatcher = pc.getMethodMatcher();
        
        if (methodMatcher == MethodMatcher.TRUE) {
            // MethodMatcher.TRUE始终返回true
            // No need to iterate the methods if we're matching any method anyway...
            return true;
        }

        // MethodMatcher下面还有一个IntroductionAwareMethodMatcher子接口
        //              AspectJExpressionPointcut类实现了IntroductionAwareMethodMatcher接口
        IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
        
        if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
            introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
        }
		
        // 获取到目标类targetClass实现的所有接口
        Set<Class<?>> classes = new LinkedHashSet<Class<?>>
                                          (ClassUtils.getAllInterfacesForClassAsSet(targetClass));
        
        classes.add(targetClass);
        
        // 遍历targetClass实现的所有接口
        for (Class<?> clazz : classes) {
            Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
            // 遍历每个接口的每个方法
            for (Method method : methods) {
                // 如果是IntroductionAwareMethodMatcher,那么就调用它的matches(Method, Class<?>, boolean);
                if ((introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(
                                                                                     method, 
                                                                                     targetClass, 
                                                                                     hasIntroductions)
                      ) 
                       // 如果不是,那么就调用MethodMatcher的方法了 
                    || methodMatcher.matches(method, targetClass)) {
                    return true;
                }
            }
        }

        return false;
    }



}

AspectJAwareAdvisorAutoProxyCreator

上面我们看到了AbstractAdvisorAutoProxyCreator是直接在BeanFactory中查找Advisor类型的Bean,那么AspectJAwareAdvisorAutoProxyCreator又做了什么?添加了一个Advisor,用来暴露AspectJ的方法调用对象,并对来自同一切面的多个Advisor在AspectJ中的优先级规则排序

public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {

    private static final Comparator<Advisor> 
                             DEFAULT_PRECEDENCE_COMPARATOR = new AspectJPrecedenceComparator();

	// 重写了排序方法
    @Override
    @SuppressWarnings("unchecked")
    protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
        
        List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors =
                                  new ArrayList<PartiallyComparableAdvisorHolder>(advisors.size());、
            
        for (Advisor element : advisors) {
            partiallyComparableAdvisors.add(
                new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR));
        }
        
        // 将排序委托给PartialOrder.sort(..)方法...
        List<PartiallyComparableAdvisorHolder> sorted = PartialOrder.sort(partiallyComparableAdvisors);
        if (sorted != null) {
            List<Advisor> result = new ArrayList<Advisor>(advisors.size());
            for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {
                result.add(pcAdvisor.getAdvisor());
            }
            return result;
        }
        else {
            // 没排出结果出来,还是用父类的
            return super.sortAdvisors(advisors);
        }
    }

    // 使用AspectJ切点表达式的方式的话,那么就往切面里面添加一个切面:ExposeInvocationInterceptor.ADVISOR
    //                                                类型是:DefaultPointcutAdvisor(INSTANCE)
    //                                             INSTANCE:ExposeInvocationInterceptor 
    // 而且加的位置在第一个,用来把当前的方法调用对象MethodInvocation存起来,方便之后的AspectJ风格的调用
    @Override
    protected void extendAdvisors(List<Advisor> candidateAdvisors) {
        AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
    }

    // 重写了需要忽略的beanClass&beanName
    @Override
    protected boolean shouldSkip(Class<?> beanClass, String beanName) {
        // 获取到所有的切面,如果切面是AspectJPointcutAdvisor,
        //                那么获取切面的名字,这些是作为切面的bean,所以需要跳过
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        for (Advisor advisor : candidateAdvisors) {
            if (advisor instanceof AspectJPointcutAdvisor) {
                if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
                    return true;
                }
            }
        }
        return super.shouldSkip(beanClass, beanName);
    }

}

Advisor

我们不妨再看下Advisor的继承树,下面有两大分支PointAdvisor(方法级别)和IntroductionAdvisor(类级别)的切面。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JAHiKuG8-1623858305950)(assets/image-20210615115641479.png)]

InstantiationModelAwarePointcutAdvisorImpl

我们可以发现@MethodBefore、@Around、@AfterReturning、@After、@AfterThrowing标注的方法都被封装成了**InstantiationModelAwarePointcutAdvisorImpl**,即被这些注解标注的方法的所有元信息都被封装到这个类里面去了。这个类里面就组合了AspectJExpressionPointcuts。

AnnotationAwareAspectJAutoProxyCreator

前面我们也可以看出不足之处在于,我们需要自己手动的定义Advisor这样的bean到spring容器中,那么spring就能替我们找到这些切面,然后应用它们。为了方便,spring提供以注解的方式,帮我们根据注解信息创建Advisor,并应用它们。那么接下来就看看spring是如何做的。

public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {

    // 正则,标注了@Aspect注解,同时beanName又满足这些正则的bean才会被处理
    private List<Pattern> includePatterns;

    // 默认实现是ReflectiveAspectJAdvisorFactory(此对象中将会传入beanFactory工厂),
    // 用于解析每一个bean是否为切面类,并且解析其中的每一个标注了aspectj相关的注解,返回成List<Advisor>
    private AspectJAdvisorFactory aspectJAdvisorFactory;

    // 默认实现是BeanFactoryAspectJAdvisorsBuilderAdapter(此对象中也会传入beanFactory工厂)
    // 同时此对象中还会将上面的aspectJAdvisorFactory也传进去
    private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;


    // 设置正则
    public void setIncludePatterns(List<String> patterns) {
        this.includePatterns = new ArrayList<Pattern>(patterns.size());
        for (String patternText : patterns) {
            this.includePatterns.add(Pattern.compile(patternText));
        }
    }

    // 设置AspectJAdvisorFactory属性
    public void setAspectJAdvisorFactory(AspectJAdvisorFactory aspectJAdvisorFactory) {
        Assert.notNull(aspectJAdvisorFactory, "AspectJAdvisorFactory must not be null");
        this.aspectJAdvisorFactory = aspectJAdvisorFactory;
    }

    // 重写方法,将aspectJAdvisorFactory和BeanFactoryAspectJAdvisorsBuilderAdapter对象组合起来
    @Override
    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        super.initBeanFactory(beanFactory);
        if (this.aspectJAdvisorFactory == null) {
            this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
        }
        this.aspectJAdvisorsBuilder =
            new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
    }

	// 重写父类方法,除了调用父类方法,自身也到beanFactory中按照自己的规则查找切面
    @Override
    protected List<Advisor> findCandidateAdvisors() {
        // Add all the Spring advisors found according to superclass rules.
        List<Advisor> advisors = super.findCandidateAdvisors();
        // Build Advisors for all AspectJ aspects in the bean factory.
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        return advisors;
    }

    // 重写方法
    @Override
    protected boolean isInfrastructureClass(Class<?> beanClass) {
        return (super.isInfrastructureClass(beanClass) 
                  // 将 aspectJAdvisorFactory认定的切面也认为是框架中的,也就是说这些class的bean不能被代理
                ||this.aspectJAdvisorFactory.isAspect(beanClass));
    }

    // 使用正则判断beanName是否应该作为切面,匹配到任何一个正则,都算作符合条件
    // 此方法将会被内部类BeanFactoryAspectJAdvisorsBuilder调用(第二遍看到这个技巧了)
    protected boolean isEligibleAspectBean(String beanName) {
        if (this.includePatterns == null) {
            return true;
        }
        else {
            for (Pattern pattern : this.includePatterns) {
                if (pattern.matcher(beanName).matches()) {
                    return true;
                }
            }
            return false;
        }
    }


    // 传入beanFactory和AspectJAdvisorFactory对象到这个builder中去,并使用这个builder去构建List<Advisor>
    private class BeanFactoryAspectJAdvisorsBuilderAdapter extends BeanFactoryAspectJAdvisorsBuilder {

        public BeanFactoryAspectJAdvisorsBuilderAdapter(
            ListableBeanFactory beanFactory, AspectJAdvisorFactory advisorFactory) {

            super(beanFactory, advisorFactory);
        }

        @Override
        protected boolean isEligibleBean(String beanName) {
            return AnnotationAwareAspectJAutoProxyCreator.this.isEligibleAspectBean(beanName);
        }
    }

}

我们现在已经知道了AnnotationAwareAspectJAutoProxyCreator其实相当于只改写了获取切面的逻辑,并且使用BeanFactoryAspectJAdvisorsBuilder和AspectJAdvisorFactory组合起来从beanFactory中获取切面,下面具体看看这两个对象是怎么找的。

BeanFactoryAspectJAdvisorsBuilder

public class BeanFactoryAspectJAdvisorsBuilder {

    // 查找的beanFactory
    private final ListableBeanFactory beanFactory;

    // 切面工厂,用来根据bean构建切面
    private final AspectJAdvisorFactory advisorFactory;

    // 缓存,因为是切面的bean只需要从beanFactory中查找一次,然后把这些bean的名字(aspectName)缓存起来
    private volatile List<String> aspectBeanNames;

    // 根据aspectName,缓存与之对应解析的List<Advisor>
    private final Map<String, List<Advisor>> 
                                   advisorsCache = new ConcurrentHashMap<String,List<Advisor>>();

    private final 
        Map<String, MetadataAwareAspectInstanceFactory> 
        aspectFactoryCache = new ConcurrentHashMap<String, MetadataAwareAspectInstanceFactory>();



	// AspectJAdvisorFactory的默认实现就是ReflectiveAspectJAdvisorFactory
    public BeanFactoryAspectJAdvisorsBuilder(ListableBeanFactory beanFactory) {
        this(beanFactory, new ReflectiveAspectJAdvisorFactory(beanFactory));
    }

    public BeanFactoryAspectJAdvisorsBuilder(ListableBeanFactory beanFactory, 
                                             AspectJAdvisorFactory advisorFactory) {
        Assert.notNull(beanFactory, "ListableBeanFactory must not be null");
        Assert.notNull(advisorFactory, "AspectJAdvisorFactory must not be null");
        this.beanFactory = beanFactory;
        this.advisorFactory = advisorFactory;
    }


    /**
    * 查找AspectJ注解的切面bean,并且返回成spring aop的切面
    * 为每个AspectJ标注的增强方法创建Spring Advisor切面
    */
    public List<Advisor> buildAspectJAdvisors() {
        // 先从缓存中找
        List<String> aspectNames = this.aspectBeanNames;

        if (aspectNames == null) {
            synchronized (this) {
                // 双重if
                aspectNames = this.aspectBeanNames;
                
                if (aspectNames == null) {
                    List<Advisor> advisors = new LinkedList<Advisor>();
                    aspectNames = new LinkedList<String>();
                    
                    // 获取beanFactory中的所有bean(包括非单例bean)
                    String[] beanNames = BeanFactoryUtils
                                                  .beanNamesForTypeIncludingAncestors(this.beanFactory, 
                                                                                      Object.class, 
                                                                                      true, false);
                    
                    for (String beanName : beanNames) {
                        
                        // 注意一下,这个判断,BeanFactoryAspectJAdvisorsBuilderAdapter重写了这个方法,
                        //                 (直接排除掉这个beanName,这里使用的是正则排除掉)
                        if (!isEligibleBean(beanName)) {
                            continue;
                        }
                        
                        // 去拿bean的class
                        // 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.
                        Class<?> beanType = this.beanFactory.getType(beanName);
                        
                        if (beanType == null) {
                            continue;
                        }
                        
                        // 使用AspectJAdvisorFactory判断是不是定了切面的bean
                        //    条件就是这个beanClass有@Aspect注解,并且不能是ajc编译器编译过来的class
                        if (this.advisorFactory.isAspect(beanType)) {
                            
                            // 有@Aspect这个注解的话,就缓存这个bean的名字
                            aspectNames.add(beanName);
                            
                            // 先存放到AspectMetadata,里面会根据@Aspect注解里面的value值来做判断
                            AspectMetadata amd = new AspectMetadata(beanType, beanName);
                            
                            // Aspect又分为不同的类型SINGLETON、PERTHIS、PERTARGET、PERCFLOW、
                            //                     PERCFLOWBELOW、PERTYPEWITHIN
                            // 如果@Aspect上面没写啥,那就是SINGLETON
                            // 注意:springAop不支持PERCFLOW、PERCFLOWBELOW
                            if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                                
                                // 将beanFactory和beanName(aspect),封装到这个工厂中去
                                MetadataAwareAspectInstanceFactory factory =
                                    new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                                
                                // 使用ReflectiveAspectJAdvisorFactory从上面这个factory中获取List<advisor>
                                //   这里面返回的Advisor就是【InstantiationModelAwarePointcutAdvisorImpl
                                //                         + AspectJExpressionPointcut】
                                // 详细下面再看
                                List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                                
                                // 如果这个beanName的bean是个单例,那么就直接存入切面缓存
                                if (this.beanFactory.isSingleton(beanName)) {
                                    this.advisorsCache.put(beanName, classAdvisors);
                                }
                                else {
                                    // 如果不是,那么保存上面这个factory,到aspectFactoryCache的缓存
                                    this.aspectFactoryCache.put(beanName, factory);
                                }
                                advisors.addAll(classAdvisors); 
                            }
                            else {
                                // 如果@Aspect指定了其它的类型,那么这个切面bean在beanFactory工厂中不能是单例
                                // Per target or per this.
                                if (this.beanFactory.isSingleton(beanName)) {
                                    throw new IllegalArgumentException("Bean with name '" + beanName +
                                                                       "' is a singleton, but aspect"
                                                                       +"instantiation model is not
                                                                       +"singleton");
                                }
                                
                                // 与上面的同样封装
                                MetadataAwareAspectInstanceFactory factory =
                                    new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                                
                                // 也就是说如果@Aspect指定了其它类型,那么也将它放入aspectFactoryCache的缓存
                                this.aspectFactoryCache.put(beanName, factory);
                                
                                // 添加到切面里面
                                advisors.addAll(this.advisorFactory.getAdvisors(factory));
                            }
                        }
                    }
                    this.aspectBeanNames = aspectNames;
                    return advisors;
                }
            }
        }

        // 说明beanFactory中没有@Aspect注解标注的切面bean
        if (aspectNames.isEmpty()) {
            return Collections.emptyList();
        }
        
        List<Advisor> advisors = new LinkedList<Advisor>();
        
        for (String aspectName : aspectNames) {
            
            // 根据aspectName来拿,如果不在advisorsCache里面,那么就在aspectFactoryCache里面
            // 所以拿到切面
            
            List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
            
            if (cachedAdvisors != null) {
                advisors.addAll(cachedAdvisors);
            }
            else {
                MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
                advisors.addAll(this.advisorFactory.getAdvisors(factory));
            }
        }
        
        return advisors;
    }

    // 被子类BeanFactoryAspectJAdvisorsBuilderAdapter重写,
    //     从而转向调用AnnotationAwareAspectJAutoProxyCreator的isEligibleBean方法
    protected boolean isEligibleBean(String beanName) {
        return true;
    }

}
AspectMetadata

在开始说AspectJAdvisorFactory之前,还是先看看上面的AspectMetadata,下面这一句,传入了beanClass和beanName组成切面元信息。

AspectMetadata amd = new AspectMetadata(beanType, beanName);
public class AspectMetadata implements Serializable {

    /**
    * The name of this aspect as defined to Spring (the bean name) -
    * allows us to determine if two pieces of advice come from the
    * same aspect and hence their relative precedence.
    */
    private final String aspectName;

    /**
    * The aspect class, stored separately for re-resolution of the
    * corresponding AjType on deserialization.
    */
    private final Class<?> aspectClass;

    /**
    * AspectJ reflection information (AspectJ 5 / Java 5 specific).
    * Re-resolved on deserialization since it isn't serializable itself.
    */
    private transient AjType<?> ajType;

    /**
    * Spring AOP pointcut corresponding to the per clause of the
    * aspect. Will be the Pointcut.TRUE canonical instance in the
    * case of a singleton, otherwise an AspectJExpressionPointcut.
    */
    private final Pointcut perClausePointcut;


    /**
    * Create a new AspectMetadata instance for the given aspect class.
    * @param aspectClass the aspect class
    * @param aspectName the name of the aspect
    */
    public AspectMetadata(Class<?> aspectClass, String aspectName) {
        
        // 就是beanName
        this.aspectName = aspectName;

        // 就是beanClass
        Class<?> currClass = aspectClass;
        
        AjType<?> ajType = null;
        
        while (currClass != Object.class) {
            // 将当前类封装成AjTypeImpl
            AjType<?> ajTypeToCheck = AjTypeSystem.getAjType(currClass);
            if (ajTypeToCheck.isAspect()) {
                ajType = ajTypeToCheck;
                break;
            }
            currClass = currClass.getSuperclass();
        }
        
        if (ajType == null) {
            throw new IllegalArgumentException("Class '" + aspectClass.getName() 
                                               + "' is not an @AspectJ aspect");
        }
        
        if (ajType.getDeclarePrecedence().length > 0) {
            throw new IllegalArgumentException("DeclarePrecendence not presently supported "+
                                               "in Spring AOP");
        }
        
        this.aspectClass = ajType.getJavaClass();
        this.ajType = ajType;

        // 获取ajType的类型
        switch (this.ajType.getPerClause().getKind()) {
            case SINGLETON: // 默认是SINGLETON
                this.perClausePointcut = Pointcut.TRUE;
                return;
            case PERTARGET:
            case PERTHIS:
                AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
                ajexp.setLocation(aspectClass.getName());
                ajexp.setExpression(findPerClause(aspectClass));
                ajexp.setPointcutDeclarationScope(aspectClass);
                this.perClausePointcut = ajexp;
                return;
            case PERTYPEWITHIN:
                // Works with a type pattern
                this.perClausePointcut = new ComposablePointcut(new TypePatternClassFilter(
                                                                    findPerClause(aspectClass)));
                return;
            default:
                throw new AopConfigException(
                    "PerClause " + ajType.getPerClause().getKind() 
                    + " not supported by Spring AOP for " + aspectClass);
        }
    }

    /**
    * Extract contents from String of form {@code pertarget(contents)}.
    */
    private String findPerClause(Class<?> aspectClass) {
        String str = aspectClass.getAnnotation(Aspect.class).value();
        str = str.substring(str.indexOf("(") + 1);
        str = str.substring(0, str.length() - 1);
        return str;
    }

    /**
    * Return whether the aspect is defined as "perthis" or "pertarget".
    */
    public boolean isPerThisOrPerTarget() {
        PerClauseKind kind = getAjType().getPerClause().getKind();
        return (kind == PerClauseKind.PERTARGET || kind == PerClauseKind.PERTHIS);
    }

    /**
    * Return whether the aspect is defined as "pertypewithin".
    */
    public boolean isPerTypeWithin() {
        PerClauseKind kind = getAjType().getPerClause().getKind();
        return (kind == PerClauseKind.PERTYPEWITHIN);
    }

    /**
    * Return whether the aspect needs to be lazily instantiated.
    */
    public boolean isLazilyInstantiated() {
        return (isPerThisOrPerTarget() || isPerTypeWithin());
    }


    private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
        inputStream.defaultReadObject();
        this.ajType = AjTypeSystem.getAjType(this.aspectClass);
    }

}

上面又用到这个类

/**
 * This is the anchor for the AspectJ runtime type system. 
 * Typical usage to get the AjType representation of a given type
 * at runtime is to call <code>AjType<Foo> fooType = AjTypeSystem.getAjType(Foo.class);</code>
 */
public class AjTypeSystem {

    private static Map<Class, WeakReference<AjType>> ajTypes = 
        Collections.synchronizedMap(new WeakHashMap<Class,WeakReference<AjType>>());

    /**
		 * Return the AspectJ runtime type representation of the given Java type.
		 * Unlike java.lang.Class, AjType understands pointcuts, advice, declare statements,
		 * and other AspectJ type members. AjType is the recommended reflection API for
		 * AspectJ programs as it offers everything that java.lang.reflect does, with 
		 * AspectJ-awareness on top.
		 */
    public static <T> AjType<T> getAjType(Class<T> fromClass) {
        WeakReference<AjType> weakRefToAjType =  ajTypes.get(fromClass);
        if (weakRefToAjType!=null) {
            AjType<T> theAjType = weakRefToAjType.get();
            if (theAjType != null) {
                return theAjType;
            } else {
                theAjType = new AjTypeImpl<T>(fromClass);
                ajTypes.put(fromClass, new WeakReference<AjType>(theAjType));
                return theAjType;
            }
        }
        // neither key nor value was found
        AjType<T> theAjType =  new AjTypeImpl<T>(fromClass); // 默认根据一个类返回AjTypeImpl
        ajTypes.put(fromClass, new WeakReference<AjType>(theAjType));
        return theAjType;
    }
    
    // 获取@Aspect注解
    public boolean isAspect() {
		return clazz.getAnnotation(Aspect.class) != null;
	}
    
}

再看看这个类

public class AjTypeImpl<T> implements AjType<T> {
    private static final String ajcMagic = "ajc$";

    private Class<T> clazz;
    private Pointcut[] declaredPointcuts = null;
    private Pointcut[] pointcuts = null;
    private Advice[] declaredAdvice = null;
    private Advice[] advice = null;
    private InterTypeMethodDeclaration[] declaredITDMethods = null;
    private InterTypeMethodDeclaration[] itdMethods = null;
    private InterTypeFieldDeclaration[] declaredITDFields = null;
    private InterTypeFieldDeclaration[] itdFields = null;
    private InterTypeConstructorDeclaration[] itdCons = null;
    private InterTypeConstructorDeclaration[] declaredITDCons = null;

    public AjTypeImpl(Class<T> fromClass) {
        this.clazz = fromClass;
    }
    
    public PerClause getPerClause() {
		if (isAspect()) {
            
			Aspect aspectAnn = clazz.getAnnotation(Aspect.class);
            
            // @Aspect注解上还可以写value
			String perClause = aspectAnn.value();
            
			if (perClause.equals("")) {
                // 如果@Aspect注解上没写value,那么看父类有没有写@Aspect,如果有那就用父类的
				if (getSupertype().isAspect()) {
					return getSupertype().getPerClause();
				} 
				return new PerClauseImpl(PerClauseKind.SINGLETON);
			} else if (perClause.startsWith("perthis(")) {
				return new PointcutBasedPerClauseImpl(PerClauseKind.PERTHIS,perClause.substring(
                    "perthis(".length(),perClause.length() - 1));
			} else if (perClause.startsWith("pertarget(")) {
				return new PointcutBasedPerClauseImpl(PerClauseKind.PERTARGET,perClause.substring(
                    "pertarget(".length(),perClause.length() - 1));				
			} else if (perClause.startsWith("percflow(")) {
				return new PointcutBasedPerClauseImpl(PerClauseKind.PERCFLOW,perClause.substring(
                    "percflow(".length(),perClause.length() - 1));								
			} else if (perClause.startsWith("percflowbelow(")) {
				return new PointcutBasedPerClauseImpl(PerClauseKind.PERCFLOWBELOW,perClause.substring(
                    "percflowbelow(".length(),perClause.length() - 1));
			} else if (perClause.startsWith("pertypewithin")) {
				return new TypePatternBasedPerClauseImpl(PerClauseKind.PERTYPEWITHIN,
                                                         perClause.substring("pertypewithin(" .length()
                                                         ,perClause.length() - 1));				
			} else {
				throw new IllegalStateException("Per-clause not recognized: " + perClause);
			}
		} else {
			return null;
		}
	}
    
    // 将superClass封装成AjTypeImpl对象
    public AjType<? super T> getSupertype() {
		Class<? super T> superclass = clazz.getSuperclass();
		return superclass==null ? null : (AjType<? super T>) new AjTypeImpl(superclass);
	}
    
    // ajc中的注解有很多呀,springAop只是部分支持了
    private boolean isReallyAMethod(Method method) {
		if (method.getName().startsWith(ajcMagic)) return false;
		if (method.getAnnotations().length==0) return true;
		if (method.isAnnotationPresent(org.aspectj.lang.annotation.Pointcut.class)) return false;
		if (method.isAnnotationPresent(Before.class)) return false;
		if (method.isAnnotationPresent(After.class)) return false;
		if (method.isAnnotationPresent(AfterReturning.class)) return false;
		if (method.isAnnotationPresent(AfterThrowing.class)) return false;
		if (method.isAnnotationPresent(Around.class)) return false;
		return true;
	}
    
    // ...省略
    
}
BeanFactoryAspectInstanceFactory
MetadataAwareAspectInstanceFactory factory =
      new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); // 传入切面的beanName

很简单的一个类,实现了MetadataAwareAspectInstanceFactory接口

public class BeanFactoryAspectInstanceFactory 
                                  implements MetadataAwareAspectInstanceFactory, Serializable {

	private final BeanFactory beanFactory;

	private final String name;

	private final AspectMetadata aspectMetadata;


	public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name) {
		this(beanFactory, name, beanFactory.getType(name));
	}

	public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name, Class<?> type) {
		Assert.notNull(beanFactory, "BeanFactory must not be null");
		Assert.notNull(name, "Bean name must not be null");
		this.beanFactory = beanFactory;
		this.name = name;
		this.aspectMetadata = new AspectMetadata(type, name);
	}


	@Override
	public Object getAspectInstance() {
		return this.beanFactory.getBean(this.name);
	}

	@Override
	public ClassLoader getAspectClassLoader() {
		return (this.beanFactory instanceof ConfigurableBeanFactory ?
				((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
				ClassUtils.getDefaultClassLoader());
	}

	@Override
	public AspectMetadata getAspectMetadata() {
		return this.aspectMetadata;
	}

	@Override
	public Object getAspectCreationMutex() {
		if (this.beanFactory != null) {
			if (this.beanFactory.isSingleton(name)) {
				// Rely on singleton semantics provided by the factory -> no local lock.
				return null;
			}
			else if (this.beanFactory instanceof ConfigurableBeanFactory) {
				// No singleton guarantees from the factory -> let's lock locally but
				// reuse the factory's singleton lock, just in case a lazy dependency
				// of our advice bean happens to trigger the singleton lock implicitly...
				return ((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex();
			}
		}
		return this;
	}
    
	@Override
	public int getOrder() {
		Class<?> type = this.beanFactory.getType(this.name);
		if (type != null) {
			if (Ordered.class.isAssignableFrom(type) && this.beanFactory.isSingleton(this.name)) {
				return ((Ordered) this.beanFactory.getBean(this.name)).getOrder();
			}
			return OrderUtils.getOrder(type, Ordered.LOWEST_PRECEDENCE);
		}
		return Ordered.LOWEST_PRECEDENCE;
	}


	@Override
	public String toString() {
		return getClass().getSimpleName() + ": bean name '" + this.name + "'";
	}

}
PrototypeAspectInstanceFactory
public class PrototypeAspectInstanceFactory extends BeanFactoryAspectInstanceFactory 
                                                                       implements Serializable {

   /**
    * Create a PrototypeAspectInstanceFactory. AspectJ will be called to
    * introspect to create AJType metadata using the type returned for the
    * given bean name from the BeanFactory.
    * @param beanFactory the BeanFactory to obtain instance(s) from
    * @param name the name of the bean
    */
   public PrototypeAspectInstanceFactory(BeanFactory beanFactory, String name) {
      super(beanFactory, name);
      if (!beanFactory.isPrototype(name)) {
         throw new IllegalArgumentException(
               "Cannot use PrototypeAspectInstanceFactory with bean named '" 
               + name + "': not a prototype");
      }
   }

}

AbstractAspectJAdvisorFactory

这个类就是用来解析切面类中的AjpectJ注解的,比较重要。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HpFQXrGa-1623858305952)(assets/image-20210615153350483.png)]

先看看父类提前做好了什么准备工作

public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFactory {

    private static final String AJC_MAGIC = "ajc$";


    /** Logger available to subclasses */
    protected final Log logger = LogFactory.getLog(getClass());

    protected final ParameterNameDiscoverer        // 参数名发现器
        parameterNameDiscoverer = new AspectJAnnotationParameterNameDiscoverer();

    // 是否为Aspect,是根据是否有Aspect注解来判断的,并且不能使用ajc编译器
    @Override
    public boolean isAspect(Class<?> clazz) {
        return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
    }

    private boolean hasAspectAnnotation(Class<?> clazz) {
        return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
    }

    // ajc编译器编译的字段名是固定AJC_MAGIC打头的
    private boolean compiledByAjc(Class<?> clazz) {
        for (Field field : clazz.getDeclaredFields()) {
            if (field.getName().startsWith(AJC_MAGIC)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void validate(Class<?> aspectClass) throws AopConfigException {

        // 如果父类也有@Aspect注解,那么父类就必须是抽象类
        if (aspectClass.getSuperclass().getAnnotation(Aspect.class) != null &&
            !Modifier.isAbstract(aspectClass.getSuperclass().getModifiers())) {
            throw new AopConfigException("[" + aspectClass.getName() 
                                         + "] cannot extend concrete aspect [" 
                                         + aspectClass.getSuperclass().getName() + "]");
        }

		// 其实就是把aspectClass包装成AjTypeImpl
        AjType<?> ajType = AjTypeSystem.getAjType(aspectClass);
        
        // 根据是否有@Aspect注解判断
        if (!ajType.isAspect()) {
            throw new NotAnAtAspectException(aspectClass);
        }
        
        // 不支持PERCFLOW、PERCFLOWBELOW
        if (ajType.getPerClause().getKind() == PerClauseKind.PERCFLOW) {
            throw new AopConfigException(aspectClass.getName()
                                         + " uses percflow instantiation model: " +
                                         "This is not supported in Spring AOP.");
        }
        if (ajType.getPerClause().getKind() == PerClauseKind.PERCFLOWBELOW) {
            throw new AopConfigException(aspectClass.getName() 
                                         + " uses percflowbelow instantiation model: " +
                                         "This is not supported in Spring AOP.");
        }
    }

    // 查找给定方法的AspectJ的注解,主要是想看下方法上是否有某个注解
    @SuppressWarnings("unchecked")
    protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
        
        Class<?>[] classesToLookFor = new Class<?>[] {
            Before.class, 
            Around.class, 
            After.class, 
            AfterReturning.class, 
            AfterThrowing.class, 
            Pointcut.class};
        
        for (Class<?> c : classesToLookFor) {
            AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);
            if (foundAnnotation != null) {
                return foundAnnotation;
            }
        }
        return null;
    }

    // 查找方法上指定的注解
    private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, 
                                                                              Class<A> toLookFor) {
        A result = AnnotationUtils.findAnnotation(method, toLookFor);
        if (result != null) {
            return new AspectJAnnotation<A>(result);
        }
        else {
            return null;
        }
    }

	// AspectJ注解的类型
    protected enum AspectJAnnotationType {
        AtPointcut,
        AtBefore,
        AtAfter,
        AtAfterReturning,
        AtAfterThrowing,
        AtAround
    }


    // 内置的AspectJ注解的支持
    protected static class AspectJAnnotation<A extends Annotation> {

        private static final String[] EXPRESSION_PROPERTIES = new String[] {"value", "pointcut"};

        private static Map<Class<?>, AspectJAnnotationType> annotationTypes =
            new HashMap<Class<?>, AspectJAnnotationType>();

        static {
            annotationTypes.put(Pointcut.class,AspectJAnnotationType.AtPointcut);
            annotationTypes.put(After.class,AspectJAnnotationType.AtAfter);
            annotationTypes.put(AfterReturning.class,AspectJAnnotationType.AtAfterReturning);
            annotationTypes.put(AfterThrowing.class,AspectJAnnotationType.AtAfterThrowing);
            annotationTypes.put(Around.class,AspectJAnnotationType.AtAround);
            annotationTypes.put(Before.class,AspectJAnnotationType.AtBefore);
        }

        private final A annotation;

        private final AspectJAnnotationType annotationType;

        private final String pointcutExpression;

        private final String argumentNames;

        public AspectJAnnotation(A annotation) {
            this.annotation = annotation;
            this.annotationType = determineAnnotationType(annotation);
            // We know these methods exist with the same name on each object,
            // but need to invoke them reflectively as there isn't a common interface.
            try {
                this.pointcutExpression = resolveExpression(annotation);
                this.argumentNames = (String) annotation.getClass()
                                                        .getMethod("argNames")
                                                        .invoke(annotation);
            }
            catch (Exception ex) {
                throw new IllegalArgumentException(annotation 
                                                   + " cannot be an AspectJ annotation", ex);
            }
        }

        private AspectJAnnotationType determineAnnotationType(A annotation) {
            for (Class<?> type : annotationTypes.keySet()) {
                if (type.isInstance(annotation)) {
                    return annotationTypes.get(type);
                }
            }
            throw new IllegalStateException("Unknown annotation type: " + annotation.toString());
        }

        private String resolveExpression(A annotation) throws Exception {
            String expression = null;
            for (String methodName : EXPRESSION_PROPERTIES) {
                Method method;
                try {
                    method = annotation.getClass().getDeclaredMethod(methodName);
                }
                catch (NoSuchMethodException ex) {
                    method = null;
                }
                if (method != null) {
                    String candidate = (String) method.invoke(annotation);
                    if (StringUtils.hasText(candidate)) {
                        expression = candidate;
                    }
                }
            }
            return expression;
        }
    }

    private static class AspectJAnnotationParameterNameDiscoverer implements ParameterNameDiscoverer {

        // AspectJ注解支持value属性,用逗号隔开的参数名字
        @Override
        public String[] getParameterNames(Method method) {
            if (method.getParameterTypes().length == 0) {
                return new String[0];
            }
            AspectJAnnotation<?> annotation = findAspectJAnnotationOnMethod(method);
            if (annotation == null) {
                return null;
            }
            StringTokenizer strTok = new StringTokenizer(annotation.getArgumentNames(), ",");
            if (strTok.countTokens() > 0) {
                String[] names = new String[strTok.countTokens()];
                for (int i = 0; i < names.length; i++) {
                    names[i] = strTok.nextToken();
                }
                return names;
            }
            else {
                return null;
            }
        }

        @Override
        public String[] getParameterNames(Constructor<?> ctor) {
            throw new UnsupportedOperationException("Spring AOP cannot handle constructor advice");
        }
    }

}
ReflectiveAspectJAdvisorFactory

看下这几句

MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, 
                                                                                  beanName);
// 根据MetadataAwareAspectInstanceFactory能返回advisors
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); 

看下ReflectiveAspectJAdvisorFactory

public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory 
                                                                    implements Serializable {

    // 用来指定这些注解的排序
    private static final Comparator<Method> METHOD_COMPARATOR;

    static {
        CompoundComparator<Method> comparator = new CompoundComparator<Method>();
        comparator.addComparator(new ConvertingComparator<Method, Annotation>(
            new InstanceComparator<Annotation>(
                Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
            new Converter<Method, Annotation>() {
                @Override
                public Annotation convert(Method method) {
                    AspectJAnnotation<?> annotation =
                        AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
                    return (annotation != null ? annotation.getAnnotation() : null);
                }
            }));
        comparator.addComparator(new ConvertingComparator<Method, String>(
            new Converter<Method, String>() {
                @Override
                public String convert(Method method) {
                    return method.getName();
                }
            }));
        METHOD_COMPARATOR = comparator;
    }

	// beanFactory工厂
    private final BeanFactory beanFactory;

    public ReflectiveAspectJAdvisorFactory() {
        this(null);
    }

    public ReflectiveAspectJAdvisorFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }


    @Override
    public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
        
        // 获取到beanClass
        Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
        // 获取到beanName
        String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
        
        // 调用父类的校验方法,上面说了
        validate(aspectClass);

        // 使用装饰者模式包装aspectInstanceFactory
        // 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 LinkedList<Advisor>();
        
        // 从切面类拿到所有没有标注@PointCut的方法,包括父类/接口中的方法,遍历这些方法,并作排序
        for (Method method : getAdvisorMethods(aspectClass)) {
            
            // 将标注的封装为Advisor(这里的实现类是InstantiationModelAwarePointcutAdvisorImpl)
            // 切面对象中包括:切点表达式、增强方法、当前this切面工厂、声明顺序0、切面bean的名字
            //        注意下:当前this切面工厂有beanFactory,如果要调用切面对象的增强方法,那么就可以直接调用了
            Advisor advisor = getAdvisor(method, 
                                         lazySingletonAspectInstanceFactory, 
                                         advisors.size(), 
                                         aspectName);
            if (advisor != null) {
                // 添加到切面集合中
                advisors.add(advisor);
            }
        }

        // 如果AspectMetadata的PerClause的Kind是PERTARGET||PERTHIS||PERTYPEWITHIN的话,
        //  那么添加上SyntheticInstantiationAdvisor这个合成的切面
        // If it's a per target aspect, emit the dummy instantiating aspect.
        if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata()
                                                                     .isLazilyInstantiated()) {
            Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(
                                                               lazySingletonAspectInstanceFactory);
            advisors.add(0, instantiationAdvisor);
        }

        // 查找目标类字段上的@DeclareParents注解,并封装成DeclareParentsAdvisor切面
        // Find introduction fields.
        for (Field field : aspectClass.getDeclaredFields()) {
            Advisor advisor = getDeclareParentsAdvisor(field);
            if (advisor != null) {
                advisors.add(advisor);
            }
        }

        return advisors;
    }

    // 从切面类拿到所有没有标注@PointCut的方法,包括父类/接口中的方法,遍历这些方法,并作排序
    private List<Method> getAdvisorMethods(Class<?> aspectClass) {
        final List<Method> methods = new LinkedList<Method>();
        ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() {
            @Override
            public void doWith(Method method) throws IllegalArgumentException {
                // Exclude pointcuts 排除掉@Pointcut这个注解
                if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
                    methods.add(method);
                }
            }
        });
        // 排序
        Collections.sort(methods, METHOD_COMPARATOR);
        return methods;
    }
    
    // 查找目标类字段上的@DeclareParents注解,并封装成DeclareParentsAdvisor切面
    private Advisor getDeclareParentsAdvisor(Field introductionField) {
        // 字段上面去拿
        DeclareParents declareParents = introductionField.getAnnotation(DeclareParents.class);
        if (declareParents == null) {
            // Not an introduction field
            return null;
        }

        if (DeclareParents.class == declareParents.defaultImpl()) {
            throw new IllegalStateException("'defaultImpl' attribute must be set on DeclareParents");
        }

        return new DeclareParentsAdvisor(
            introductionField.getType(), declareParents.value(), declareParents.defaultImpl());
    }

	// 根据方法获取切面的【关键方法】
    @Override
    public Advisor getAdvisor(Method candidateAdviceMethod, 
                              MetadataAwareAspectInstanceFactory aspectInstanceFactory,
                              int declarationOrderInAspect, String aspectName) {

        // 校验一下切面类是否有@Aspect注解,以及一些spring aop不支持的情况
        validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());

        // 封装增强方法的切点表达式为【AspectJExpressionPointcut类型】
        AspectJExpressionPointcut expressionPointcut = getPointcut(candidateAdviceMethod, // 增强方法
                                                                   aspectInstanceFactory
                                                                           .getAspectMetadata()
                                                                           .getAspectClass());// 切面类                                                               
        if (expressionPointcut == null) {
            return null;
        }

        // 这里我们看到了【InstantiationModelAwarePointcutAdvisorImpl】这个切面的实现
        
        return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut,   // 切点表达式、
                                                              candidateAdviceMethod,// 增强方法
                                                              this,                 // 当前this切面工厂
                                                              aspectInstanceFactory,// 切面元信息封装工厂 
                                                              declarationOrderInAspect,  // 声明顺序
                                                              aspectName);          // 切面bean的名字
    }

    private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, 
                                                  Class<?> candidateAspectClass) {
        
       	// 从增强方法上面找到Before, Around, After, AfterReturning, AfterThrowing, Pointcut这些AspectJ注解
        AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory
                                                 .findAspectJAnnotationOnMethod(candidateAdviceMethod);
        
        if (aspectJAnnotation == null) {
            return null;
        }

        // aspectJ表达式的封装【AspectJExpressionPointcut类型】
        AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, 
                                                                        new String[0],
                                                                        new Class<?>[0]);
        // 设置切点表达式
        ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
        // beanFactory也进去了
        ajexp.setBeanFactory(this.beanFactory);
        return ajexp;
    }

	// 将AspectJ标注的增强方法,转为SpringAop支持的增强
    @Override
    public Advice getAdvice(Method candidateAdviceMethod, 
                            AspectJExpressionPointcut expressionPointcut,
                            MetadataAwareAspectInstanceFactory aspectInstanceFactory, 
                            int declarationOrder, 
                            String aspectName) {

        // 获取切面类
        Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
        
        // 校验切面类@Aspect注解,然后必须是Spring Aop支持的功能
        validate(candidateAspectClass);

        // 从增强方法上面找到Before, Around, After, AfterReturning, AfterThrowing, Pointcut这些AspectJ注解
        // (只能有一个或者说第一个)
        AspectJAnnotation<?> aspectJAnnotation =
            AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
        
        if (aspectJAnnotation == null) {
            return null;
        }

        // 还要检查一遍切面类上的@Aspect注解
        // 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);
        }
		
        // 声明spring Aop的增强
        AbstractAspectJAdvice springAdvice;

        // 【AspectJAfterThrowingAdvice、AspectJAfterAdvice、AspectJAroundAdvice】
        // 【AspectJMethodBeforeAdvice、AspectJAfterReturningAdvice】 五种Spring Aop的增强
        // 上面三个实现了MethodInterceptor接口,下面两个没有实现MethodInterceptor接口接口
        switch (aspectJAnnotation.getAnnotationType()) {
                
            case AtBefore:
                springAdvice = new AspectJMethodBeforeAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                break;
                
            case AtAfter:
                springAdvice = new AspectJAfterAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                break;
                
            case AtAfterReturning:
                springAdvice = new AspectJAfterReturningAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation
                                                                               .getAnnotation();
                if (StringUtils.hasText(afterReturningAnnotation.returning())) {
                    springAdvice.setReturningName(afterReturningAnnotation.returning());
                }
                break;
                
            case AtAfterThrowing:
                springAdvice = new AspectJAfterThrowingAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation
                                                                               .getAnnotation();
                if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
                    springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
                }
                break;
                
            case AtAround:
                springAdvice = new AspectJAroundAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                break;
                
            case AtPointcut:
                if (logger.isDebugEnabled()) {
                    logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
                }
                return null;
                
            default:
                throw new UnsupportedOperationException(
                    "Unsupported advice type on method: " + candidateAdviceMethod);
        }

        // Now to configure the advice...
        // 设置切面的名字
        springAdvice.setAspectName(aspectName);
        
        // 设置声明的顺序
        springAdvice.setDeclarationOrder(declarationOrder);
        
        // 获取注解上的value,然后逗号分隔开,返回数组
        String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
        
        if (argNames != null) {
            springAdvice.setArgumentNamesFromStringArray(argNames);
        }
        
        // 计算参数绑定,第一个参数类型是JoinPoint或ProceedingJoinPoint(环绕增强用),那么会被传递进来
        //             其它的参数的绑定有用到DefaultParameterNameDiscoverer这个参数名发现器
        springAdvice.calculateArgumentBindings();
        
        return springAdvice;
    }


    // 合成的切面
    /**
    * Synthetic advisor that instantiates the aspect.
    * Triggered by per-clause pointcut on non-singleton aspect.
    * The advice has no effect.
    */
    @SuppressWarnings("serial")
    protected static class SyntheticInstantiationAdvisor extends DefaultPointcutAdvisor {

        public SyntheticInstantiationAdvisor(final MetadataAwareAspectInstanceFactory aif) {
            super(aif.getAspectMetadata().getPerClausePointcut(), new MethodBeforeAdvice() {
                @Override
                public void before(Method method, Object[] args, Object target) {
                    // Simply instantiate the aspect
                    aif.getAspectInstance();
                }
            });
        }
    }

}

至此,我们看到了切面类中方法,一个个的被解析成InstantiationModelAwarePointcutAdvisorImpl切面。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ePJF3Adu-1623858305952)(assets/image-20210615175739125.png)]

AbstractAspectJAdvice

上面在解析注解增强方法的时候,一共解析了5种切面,它们都继承自AbstractAspectJAdvice,它们都实现了Advice接口,但是有两个接口没有实现MethodInterceptor接口哦。所以等下这两个advice将会被DefaultAdvisorAdapterRegistry适配成MethodInterceptor接口。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G3BoZAc1-1623858305953)(assets/image-20210615180427291.png)]

将会变成下面这种

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oDXVBBwC-1623858305954)(assets/image-20210615181137039.png)]

ProxyFactory

上面已经说完了切面,现在来看看是怎么根据切面创建代理的?也就是下面这句

proxyFactory.getProxy(getProxyClassLoader());

我们先来看下ProxyFactory处于继承树的什么位置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3tk0T71l-1623858305954)(assets/image-20210615181903672.png)]

先从上到下,简单的看下这几个类

ProxyConfig

就是创建代理的一些可配置项,在子类中才能看到它们的作用

public class ProxyConfig implements Serializable {
    
    private boolean proxyTargetClass = false;

    private boolean optimize = false;

    boolean opaque = false;

    boolean exposeProxy = false;

    private boolean frozen = false;
    
    public void copyFrom(ProxyConfig other) {
		Assert.notNull(other, "Other ProxyConfig object must not be null");
		this.proxyTargetClass = other.proxyTargetClass;
		this.optimize = other.optimize;
		this.exposeProxy = other.exposeProxy;
		this.frozen = other.frozen;
		this.opaque = other.opaque;
	}
    // ...
}

Advised

还有一点我们要知道AdvisedSupport实现了Advised接口,所以也就具有了Advised接口里定义的配置和功能。先看看Advised

public interface Advised extends TargetClassAware {

   /**
    * Return whether the Advised configuration is frozen,
    * in which case no advice changes can be made.
    */
   boolean isFrozen();

   /**
    * Are we proxying the full target class instead of specified interfaces?
    */
   boolean isProxyTargetClass();

   /**
    * Return the interfaces proxied by the AOP proxy.
    * <p>Will not include the target class, which may also be proxied.
    */
   Class<?>[] getProxiedInterfaces();

   /**
    * Determine whether the given interface is proxied.
    * @param intf the interface to check
    */
   boolean isInterfaceProxied(Class<?> intf);

   /**
    * Change the {@code TargetSource} used by this {@code Advised} object.
    * <p>Only works if the configuration isn't {@linkplain #isFrozen frozen}.
    * @param targetSource new TargetSource to use
    */
   void setTargetSource(TargetSource targetSource);

   /**
    * Return the {@code TargetSource} used by this {@code Advised} object.
    */
   TargetSource getTargetSource();

   /**
    * Set whether the proxy should be exposed by the AOP framework as a
    * {@link ThreadLocal} for retrieval via the {@link AopContext} class.
    * <p>It can be necessary to expose the proxy if an advised object needs
    * to invoke a method on itself with advice applied. Otherwise, if an
    * advised object invokes a method on {@code this}, no advice will be applied.
    * <p>Default is {@code false}, for optimal performance.
    */
   void setExposeProxy(boolean exposeProxy);

   /**
    * Return whether the factory should expose the proxy as a {@link ThreadLocal}.
    * <p>It can be necessary to expose the proxy if an advised object needs
    * to invoke a method on itself with advice applied. Otherwise, if an
    * advised object invokes a method on {@code this}, no advice will be applied.
    * <p>Getting the proxy is analogous to an EJB calling {@code getEJBObject()}.
    * @see AopContext
    */
   boolean isExposeProxy();

   /**
    * Set whether this proxy configuration is pre-filtered so that it only
    * contains applicable advisors (matching this proxy's target class).
    * <p>Default is "false". Set this to "true" if the advisors have been
    * pre-filtered already, meaning that the ClassFilter check can be skipped
    * when building the actual advisor chain for proxy invocations.
    * @see org.springframework.aop.ClassFilter
    */
   void setPreFiltered(boolean preFiltered);

   /**
    * Return whether this proxy configuration is pre-filtered so that it only
    * contains applicable advisors (matching this proxy's target class).
    */
   boolean isPreFiltered();

   /**
    * Return the advisors applying to this proxy.
    * @return a list of Advisors applying to this proxy (never {@code null})
    */
   Advisor[] getAdvisors();

   /**
    * Add an advisor at the end of the advisor chain.
    * <p>The Advisor may be an {@link org.springframework.aop.IntroductionAdvisor},
    * in which new interfaces will be available when a proxy is next obtained
    * from the relevant factory.
    * @param advisor the advisor to add to the end of the chain
    * @throws AopConfigException in case of invalid advice
    */
   void addAdvisor(Advisor advisor) throws AopConfigException;

   /**
    * Add an Advisor at the specified position in the chain.
    * @param advisor the advisor to add at the specified position in the chain
    * @param pos position in chain (0 is head). Must be valid.
    * @throws AopConfigException in case of invalid advice
    */
   void addAdvisor(int pos, Advisor advisor) throws AopConfigException;

   /**
    * Remove the given advisor.
    * @param advisor the advisor to remove
    * @return {@code true} if the advisor was removed; {@code false}
    * if the advisor was not found and hence could not be removed
    */
   boolean removeAdvisor(Advisor advisor);

   /**
    * Remove the advisor at the given index.
    * @param index index of advisor to remove
    * @throws AopConfigException if the index is invalid
    */
   void removeAdvisor(int index) throws AopConfigException;

   /**
    * Return the index (from 0) of the given advisor,
    * or -1 if no such advisor applies to this proxy.
    * <p>The return value of this method can be used to index into the advisors array.
    * @param advisor the advisor to search for
    * @return index from 0 of this advisor, or -1 if there's no such advisor
    */
   int indexOf(Advisor advisor);

   /**
    * Replace the given advisor.
    * <p><b>Note:</b> If the advisor is an {@link org.springframework.aop.IntroductionAdvisor}
    * and the replacement is not or implements different interfaces, the proxy will need
    * to be re-obtained or the old interfaces won't be supported and the new interface
    * won't be implemented.
    * @param a the advisor to replace
    * @param b the advisor to replace it with
    * @return whether it was replaced. If the advisor wasn't found in the
    * list of advisors, this method returns {@code false} and does nothing.
    * @throws AopConfigException in case of invalid advice
    */
   boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException;

   /**
    * Add the given AOP Alliance advice to the tail of the advice (interceptor) chain.
    * <p>This will be wrapped in a DefaultPointcutAdvisor with a pointcut that always
    * applies, and returned from the {@code getAdvisors()} method in this wrapped form.
    * <p>Note that the given advice will apply to all invocations on the proxy,
    * even to the {@code toString()} method! Use appropriate advice implementations
    * or specify appropriate pointcuts to apply to a narrower set of methods.
    * @param advice advice to add to the tail of the chain
    * @throws AopConfigException in case of invalid advice
    * @see #addAdvice(int, Advice)
    * @see org.springframework.aop.support.DefaultPointcutAdvisor
    */
   void addAdvice(Advice advice) throws AopConfigException;

   /**
    * Add the given AOP Alliance Advice at the specified position in the advice chain.
    * <p>This will be wrapped in a {@link org.springframework.aop.support.DefaultPointcutAdvisor}
    * with a pointcut that always applies, and returned from the {@link #getAdvisors()}
    * method in this wrapped form.
    * <p>Note: The given advice will apply to all invocations on the proxy,
    * even to the {@code toString()} method! Use appropriate advice implementations
    * or specify appropriate pointcuts to apply to a narrower set of methods.
    * @param pos index from 0 (head)
    * @param advice advice to add at the specified position in the advice chain
    * @throws AopConfigException in case of invalid advice
    */
   void addAdvice(int pos, Advice advice) throws AopConfigException;

   /**
    * Remove the Advisor containing the given advice.
    * @param advice the advice to remove
    * @return {@code true} of the advice was found and removed;
    * {@code false} if there was no such advice
    */
   boolean removeAdvice(Advice advice);

   /**
    * Return the index (from 0) of the given AOP Alliance Advice,
    * or -1 if no such advice is an advice for this proxy.
    * <p>The return value of this method can be used to index into
    * the advisors array.
    * @param advice AOP Alliance advice to search for
    * @return index from 0 of this advice, or -1 if there's no such advice
    */
   int indexOf(Advice advice);

   /**
    * As {@code toString()} will normally be delegated to the target,
    * this returns the equivalent for the AOP proxy.
    * @return a string description of the proxy configuration
    */
   String toProxyConfigString();

}

AdvisedSupport

我们要特别注意里面的DefaultAdvisorChainFactory,这是这个类里面特别关键的一个对象。

public class AdvisedSupport extends ProxyConfig implements Advised {

    // EmptyTargetSource实现了TargetSource接口,
    //            EmptyTargetSource.INSTANCE = new EmptyTargetSource(null, true)
    //                                         目标对象是null,isStatic属性是true
    public static final TargetSource EMPTY_TARGET_SOURCE = EmptyTargetSource.INSTANCE;


    // 默认没有目标对象
    TargetSource targetSource = EMPTY_TARGET_SOURCE;

    // 是不是之前已经过滤了,我们之前的自动代理创建器里有这个配置
    private boolean preFiltered = false;

    // 切面链工厂,默认实现DefaultAdvisorChainFactory
    //                    -> getInterceptorsAndDynamicInterceptionAdvice(Advised,Method,targetClass)
    //                       可以根据提供的Advised(包含切面数组,实现接口,创建代理的各项配置)、
    //                                   Method (目标方法)、
    //                                   targetClass (目标对象的class)
    //                       从Adised里面获取所有的切面,然后遍历这些切面,经处理后返回拦截器列表
    AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();

    // 目标方法的对应的拦截器列表缓存
    private transient Map<MethodCacheKey, List<Object>> methodCache;

    // 创建的代理需要实现的接口集合
    private List<Class<?>> interfaces = new ArrayList<Class<?>>();

    // 切面集合,之前就是一直在找切面
    private List<Advisor> advisors = new LinkedList<Advisor>();

    // 切面数组,只要advisors修改,那么advisorArray也要跟着改
    private Advisor[] advisorArray = new Advisor[0];

    // 构造方法
    public AdvisedSupport(Class<?>... interfaces) {
        this();
        setInterfaces(interfaces);
    }

    // 无参构造
    public AdvisedSupport() {
        initMethodCache();
    }

    // 初始化方法缓存
    private void initMethodCache() {
        this.methodCache = new ConcurrentHashMap<MethodCacheKey, List<Object>>(32);
    }

	// 把目标对象使用SingletonTargetSource包装一下
    public void setTarget(Object target) {
        setTargetSource(new SingletonTargetSource(target));
    }

    // 如果是null,使用EMPTY_TARGET_SOURCE
    @Override
    public void setTargetSource(TargetSource targetSource) {
        this.targetSource = (targetSource != null ? targetSource : EMPTY_TARGET_SOURCE);
    }

    // 获取目标对象
    @Override
    public TargetSource getTargetSource() {
        return this.targetSource;
    }

    // 设置目标类,target永远是null,targetClass才是指定的
    public void setTargetClass(Class<?> targetClass) {
        this.targetSource = EmptyTargetSource.forClass(targetClass);
    }

    // 获取目标类
    @Override
    public Class<?> getTargetClass() {
        return this.targetSource.getTargetClass();
    }

    // 设置切面是否已预过滤了
    @Override
    public void setPreFiltered(boolean preFiltered) {
        this.preFiltered = preFiltered;
    }

    @Override
    public boolean isPreFiltered() {
        return this.preFiltered;
    }

    // 设置切面链工厂,就是把切面根据targetClass,method转成拦截器列表
    public void setAdvisorChainFactory(AdvisorChainFactory advisorChainFactory) {
        Assert.notNull(advisorChainFactory, "AdvisorChainFactory must not be null");
        this.advisorChainFactory = advisorChainFactory;
    }

    public AdvisorChainFactory getAdvisorChainFactory() {
        return this.advisorChainFactory;
    }


    // 设置要代理须实现的接口
    public void setInterfaces(Class<?>... interfaces) {
        Assert.notNull(interfaces, "Interfaces must not be null");
        this.interfaces.clear();
        for (Class<?> ifc : interfaces) {
            addInterface(ifc);
        }
    }

    // 添加代理须实现的接口
    public void addInterface(Class<?> intf) {
        Assert.notNull(intf, "Interface must not be null");
        if (!intf.isInterface()) {
            throw new IllegalArgumentException("[" + intf.getName() + "] is not an interface");
        }
        if (!this.interfaces.contains(intf)) {
            this.interfaces.add(intf);
            adviceChanged();
        }
    }

    // 移除代理须实现的接口
    public boolean removeInterface(Class<?> intf) {
        return this.interfaces.remove(intf);
    }

    @Override
    public Class<?>[] getProxiedInterfaces() {
        return this.interfaces.toArray(new Class<?>[this.interfaces.size()]);
    }

    @Override
    public boolean isInterfaceProxied(Class<?> intf) {
        for (Class<?> proxyIntf : this.interfaces) {
            if (intf.isAssignableFrom(proxyIntf)) {
                return true;
            }
        }
        return false;
    }


    // 以下是对切面集合的增删改查
    
    @Override
    public final Advisor[] getAdvisors() {
        return this.advisorArray;
    }

    @Override
    public void addAdvisor(Advisor advisor) {
        int pos = this.advisors.size();
        addAdvisor(pos, advisor);
    }

    @Override
    public void addAdvisor(int pos, Advisor advisor) throws AopConfigException {
        if (advisor instanceof IntroductionAdvisor) {
            validateIntroductionAdvisor((IntroductionAdvisor) advisor);
        }
        addAdvisorInternal(pos, advisor);
    }

    @Override
    public boolean removeAdvisor(Advisor advisor) {
        int index = indexOf(advisor);
        if (index == -1) {
            return false;
        }
        else {
            removeAdvisor(index);
            return true;
        }
    }

    @Override
    public void removeAdvisor(int index) throws AopConfigException {
        if (isFrozen()) {
            throw new AopConfigException("Cannot remove Advisor: Configuration is frozen.");
        }
        if (index < 0 || index > this.advisors.size() - 1) {
            throw new AopConfigException("Advisor index " + index + " is out of bounds: " +
                                         "This configuration only has " + this.advisors.size() 
                                         + " advisors.");
        }

        Advisor advisor = this.advisors.get(index);
        if (advisor instanceof IntroductionAdvisor) {
            IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
            // We need to remove introduction interfaces.
            for (int j = 0; j < ia.getInterfaces().length; j++) {
                removeInterface(ia.getInterfaces()[j]);
            }
        }

        this.advisors.remove(index);
        updateAdvisorArray();
        adviceChanged();
    }

    @Override
    public int indexOf(Advisor advisor) {
        Assert.notNull(advisor, "Advisor must not be null");
        return this.advisors.indexOf(advisor);
    }

    @Override
    public boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException {
        Assert.notNull(a, "Advisor a must not be null");
        Assert.notNull(b, "Advisor b must not be null");
        int index = indexOf(a);
        if (index == -1) {
            return false;
        }
        removeAdvisor(index);
        addAdvisor(index, b);
        return true;
    }

    /**
    * Add all of the given advisors to this proxy configuration.
    * @param advisors the advisors to register
    */
    public void addAdvisors(Advisor... advisors) {
        addAdvisors(Arrays.asList(advisors));
    }

    /**
    * Add all of the given advisors to this proxy configuration.
    * @param advisors the advisors to register
    */
    public void addAdvisors(Collection<Advisor> advisors) {
        if (isFrozen()) {
            throw new AopConfigException("Cannot add advisor: Configuration is frozen.");
        }
        if (!CollectionUtils.isEmpty(advisors)) {
            for (Advisor advisor : advisors) {
                if (advisor instanceof IntroductionAdvisor) {
                    validateIntroductionAdvisor((IntroductionAdvisor) advisor);
                }
                Assert.notNull(advisor, "Advisor must not be null");
                this.advisors.add(advisor);
            }
            // 切面集合修改了,须同步修改切面数组
            updateAdvisorArray();
            
            // 切面集合修改了,需要清空方法对应的拦截器列表缓存
            adviceChanged();
        }
    }

    private void validateIntroductionAdvisor(IntroductionAdvisor advisor) {
        advisor.validateInterfaces();
        // If the advisor passed validation, we can make the change.
        Class<?>[] ifcs = advisor.getInterfaces();
        for (Class<?> ifc : ifcs) {
            addInterface(ifc);
        }
    }

    private void addAdvisorInternal(int pos, Advisor advisor) throws AopConfigException {
        Assert.notNull(advisor, "Advisor must not be null");
        if (isFrozen()) {
            throw new AopConfigException("Cannot add advisor: Configuration is frozen.");
        }
        if (pos > this.advisors.size()) {
            throw new IllegalArgumentException(
                "Illegal position " + pos + " in advisor list with size " + this.advisors.size());
        }
        this.advisors.add(pos, advisor);
        updateAdvisorArray();
        adviceChanged();
    }

    /**
    * Bring the array up to date with the list.
    */
    protected final void updateAdvisorArray() {
        this.advisorArray = this.advisors.toArray(new Advisor[this.advisors.size()]);
    }

    /**
    * Allows uncontrolled access to the {@link List} of {@link Advisor Advisors}.
    * <p>Use with care, and remember to {@link #updateAdvisorArray() refresh the advisor array}
    * and {@link #adviceChanged() fire advice changed events} when making any modifications.
    */
    protected final List<Advisor> getAdvisorsInternal() {
        return this.advisors;
    }


    @Override
    public void addAdvice(Advice advice) throws AopConfigException {
        int pos = this.advisors.size();
        addAdvice(pos, advice);
    }

    // 将增强包装为切面添加到切面集合
    /**
    * Cannot add introductions this way unless the advice implements IntroductionInfo.
    */
    @Override
    public void addAdvice(int pos, Advice advice) throws AopConfigException {
        Assert.notNull(advice, "Advice must not be null");
        if (advice instanceof IntroductionInfo) {
            // We don't need an IntroductionAdvisor for this kind of introduction:
            // It's fully self-describing.
            addAdvisor(pos, new DefaultIntroductionAdvisor(advice, (IntroductionInfo) advice));
        }
        else if (advice instanceof DynamicIntroductionAdvice) {
            // We need an IntroductionAdvisor for this kind of introduction.
            throw new AopConfigException("DynamicIntroductionAdvice may only be added as part of"+
                                         "IntroductionAdvisor");
        }
        else {
            addAdvisor(pos, new DefaultPointcutAdvisor(advice));
        }
    }

    @Override
    public boolean removeAdvice(Advice advice) throws AopConfigException {
        int index = indexOf(advice);
        if (index == -1) {
            return false;
        }
        else {
            removeAdvisor(index);
            return true;
        }
    }

    @Override
    public int indexOf(Advice advice) {
        Assert.notNull(advice, "Advice must not be null");
        for (int i = 0; i < this.advisors.size(); i++) {
            Advisor advisor = this.advisors.get(i);
            if (advisor.getAdvice() == advice) {
                return i;
            }
        }
        return -1;
    }

    /**
    * Is the given advice included in any advisor within this proxy configuration?
    * @param advice the advice to check inclusion of
    * @return whether this advice instance is included
    */
    public boolean adviceIncluded(Advice advice) {
        if (advice != null) {
            for (Advisor advisor : this.advisors) {
                if (advisor.getAdvice() == advice) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
    * Count advices of the given class.
    * @param adviceClass the advice class to check
    * @return the count of the interceptors of this class or subclasses
    */
    public int countAdvicesOfType(Class<?> adviceClass) {
        int count = 0;
        if (adviceClass != null) {
            for (Advisor advisor : this.advisors) {
                if (adviceClass.isInstance(advisor.getAdvice())) {
                    count++;
                }
            }
        }
        return count;
    }


    /**
    * Determine a list of {@link org.aopalliance.intercept.MethodInterceptor} objects
    * for the given method, based on this configuration.
    * @param method the proxied method
    * @param targetClass the target class
    * @return List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
    */
    public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, 
                                                                    Class<?> targetClass) {
        MethodCacheKey cacheKey = new MethodCacheKey(method);
        List<Object> cached = this.methodCache.get(cacheKey);
        if (cached == null) {
            cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
                this, method, targetClass);
            this.methodCache.put(cacheKey, cached);
        }
        return cached;
    }

    /**
    * Invoked when advice has changed.
    */
    protected void adviceChanged() {
        this.methodCache.clear();
    }

    /**
    * Call this method on a new instance created by the no-arg constructor
    * to create an independent copy of the configuration from the given object.
    * @param other the AdvisedSupport object to copy configuration from
    */
    protected void copyConfigurationFrom(AdvisedSupport other) {
        copyConfigurationFrom(other, other.targetSource, new ArrayList<Advisor>(other.advisors));
    }

    /**
    * Copy the AOP configuration from the given AdvisedSupport object,
    * but allow substitution of a fresh TargetSource and a given interceptor chain.
    * @param other the AdvisedSupport object to take proxy configuration from
    * @param targetSource the new TargetSource
    * @param advisors the Advisors for the chain
    */
    protected void copyConfigurationFrom(AdvisedSupport other, TargetSource targetSource, 
                                         List<Advisor> advisors) {
        copyFrom(other);
        this.targetSource = targetSource;
        this.advisorChainFactory = other.advisorChainFactory;
        this.interfaces = new ArrayList<Class<?>>(other.interfaces);
        for (Advisor advisor : advisors) {
            if (advisor instanceof IntroductionAdvisor) {
                validateIntroductionAdvisor((IntroductionAdvisor) advisor);
            }
            Assert.notNull(advisor, "Advisor must not be null");
            this.advisors.add(advisor);
        }
        updateAdvisorArray();
        adviceChanged();
    }

    /**
    * Build a configuration-only copy of this AdvisedSupport,
    * replacing the TargetSource
    */
    AdvisedSupport getConfigurationOnlyCopy() {
        AdvisedSupport copy = new AdvisedSupport();
        copy.copyFrom(this);
        copy.targetSource = EmptyTargetSource.forClass(getTargetClass(), getTargetSource().isStatic());
        copy.advisorChainFactory = this.advisorChainFactory;
        copy.interfaces = this.interfaces;
        copy.advisors = this.advisors;
        copy.updateAdvisorArray();
        return copy;
    }


    //---------------------------------------------------------------------
    // Serialization support
    //---------------------------------------------------------------------

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        // Rely on default serialization; just initialize state after deserialization.
        ois.defaultReadObject();

        // Initialize transient fields.
        initMethodCache();
    }


    @Override
    public String toProxyConfigString() {
        return toString();
    }

    /**
    * For debugging/diagnostic use.
    */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(getClass().getName());
        sb.append(": ").append(this.interfaces.size()).append(" interfaces ");
        sb.append(ClassUtils.classNamesToString(this.interfaces)).append("; ");
        sb.append(this.advisors.size()).append(" advisors ");
        sb.append(this.advisors).append("; ");
        sb.append("targetSource [").append(this.targetSource).append("]; ");
        sb.append(super.toString());
        return sb.toString();
    }


    /**
    * Simple wrapper class around a Method. Used as the key when
    * caching methods, for efficient equals and hashCode comparisons.
    */
    private static final class MethodCacheKey implements Comparable<MethodCacheKey> {

        private final Method method;

        private final int hashCode;

        public MethodCacheKey(Method method) {
            this.method = method;
            this.hashCode = method.hashCode();
        }

        @Override
        public boolean equals(Object other) {
            return (this == other || (other instanceof MethodCacheKey &&
                                      this.method == ((MethodCacheKey) other).method));
        }

        @Override
        public int hashCode() {
            return this.hashCode;
        }

        @Override
        public String toString() {
            return this.method.toString();
        }

        @Override
        public int compareTo(MethodCacheKey other) {
            int result = this.method.getName().compareTo(other.method.getName());
            if (result == 0) {
                result = this.method.toString().compareTo(other.method.toString());
            }
            return result;
        }
    }

}

DefaultAdvisorChainFactory

根据代理工厂的配置(主要是代理工厂中的切面),和目标方法&目标对象的class,返回需要被应用的拦截器

public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {

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

        // 拦截器列表,最终返回的对象
        // This is somewhat tricky... We have to process introductions first,
        // but we need to preserve order in the ultimate list.
        List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
        
        // 目标类对象
        Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
        
        // 遍历代理工厂配置中的所有的切面,判断是否存在IntroductionAdvisor,并且这个切面能够匹配上actualClass
        boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
        
        // 切面适配器,默认实现是DefaultAdvisorAdapterRegistry,用于将切面适配成MethodInterceptor接口
        //                       其中默认注册了 MethodBeforeAdviceAdapter、
        //                                    AfterReturningAdviceAdapter、
        //                                    ThrowsAdviceAdapter
        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();

        // 遍历代理工厂配置中的所有切面
        for (Advisor advisor : config.getAdvisors()) {
            
            // 如果是 PointcutAdvisor
            if (advisor instanceof PointcutAdvisor) {
                
                // Add it conditionally.
                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
                
                // 看这里就用到了PreFiltered属性,如果为true,相当于类级别的就不用检查了
                if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter()
                                                                           .matches(actualClass)) {
                    
                    // 重点:【将PointcutAdvisor类型的切面适配成MethodInterceptor接口数组】
                    MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
                    
                    // 然后作方法匹配
                    MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                    
                   
                    // ((mm instanceof IntroductionAwareMethodMatcher &&
			        // ((IntroductionAwareMethodMatcher) mm).matches(method, targetClass, 
                    //                                                       hasIntroductions))
                    //  || mm.matches(method, targetClass));
				
                    if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
                        
                        if (mm.isRuntime()) {
                            // 都封装成InterceptorAndDynamicMethodMatcher
                            //              这就只有MethodInterceptor、MethodMatcher两个属性的普通类
                            // 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;
                
                // PreFiltered属性,如果为true,相当于类级别的就不用检查了
                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;
    }

    // 所有的切面中是否有匹配指定类的IntroductionAdvisor切面
    private static boolean hasMatchingIntroductions(Advised config, Class<?> actualClass) {
        for (int i = 0; i < config.getAdvisors().length; i++) {
            Advisor advisor = config.getAdvisors()[i];
            if (advisor instanceof IntroductionAdvisor) {
                IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
                if (ia.getClassFilter().matches(actualClass)) {
                    return true;
                }
            }
        }
        return false;
    }

}
DefaultAdvisorAdapterRegistry

我们可以先知道,这些增强要应用到代理对象前,需要先适配成MethodInterceptor接口

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {

    private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);


    // 默认注册了3个适配器,用来处理 MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice 的增强
    /**
    * Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters.
    */
    public DefaultAdvisorAdapterRegistry() {
        registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
        registerAdvisorAdapter(new AfterReturningAdviceAdapter());
        registerAdvisorAdapter(new ThrowsAdviceAdapter());
    }


    @Override
    public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
        
        // advisor直接返回
        if (adviceObject instanceof Advisor) {
            return (Advisor) adviceObject;
        }
        
        // 不是切面,就必须实现Advice接口
        if (!(adviceObject instanceof Advice)) {
            throw new UnknownAdviceTypeException(adviceObject);
        }
        
        Advice advice = (Advice) adviceObject;
        
        // 包装Advice,使用DefaultPointcutAdvisor包装成切面
        
        if (advice instanceof MethodInterceptor) {
            // So well-known it doesn't even need an adapter.
            return new DefaultPointcutAdvisor(advice);
        }
        
        for (AdvisorAdapter adapter : this.adapters) {
            // Check that it is supported.
            if (adapter.supportsAdvice(advice)) {
                return new DefaultPointcutAdvisor(advice);
            }
        }
        // 如果适配器不支持增强,那么就会抛出异常
        throw new UnknownAdviceTypeException(advice);
    }

    // 刚好和上面这个方法呼应,上面将Object适配成切面,下面将切面适配成拦截器
    @Override
    public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
        
        List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
        
        // 【从切面中获取增强】
        //      下面看看 InstantiationModelAwarePointcutAdvisorImpl 的getAdvice()方法实现
        Advice advice = advisor.getAdvice();
        
        // 【将增强适配成MethodInterceptor接口】
        if (advice instanceof MethodInterceptor) {
            interceptors.add((MethodInterceptor) advice);
        }
        
        for (AdvisorAdapter adapter : this.adapters) {
            if (adapter.supportsAdvice(advice)) {
                interceptors.add(adapter.getInterceptor(advisor));
            }
        }
        
        if (interceptors.isEmpty()) {
            throw new UnknownAdviceTypeException(advisor.getAdvice());
        }
        return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
    }

    // 注册适配器
    @Override
    public void registerAdvisorAdapter(AdvisorAdapter adapter) {
        this.adapters.add(adapter);
    }

}
InstantiationModelAwarePointcutAdvisorImpl

Advice advice = advisor.getAdvice();,从切面中获取增强的逻辑

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MjcnmnMd-1623858305955)(assets/image-20210616223931213.png)]

ProxyCreatorSupport

这个类用来支持创建Aop代理的

public class ProxyCreatorSupport extends AdvisedSupport {

    // Aop代理工厂,创建Aop代理的工厂,默认实现是DefaultAopProxyFactory
    private AopProxyFactory aopProxyFactory;

    // 观察者模式:当当前类调用activated()方法或者adviceChanged()方法时,将会回调监听器的方法
    private List<AdvisedSupportListener> listeners = new LinkedList<AdvisedSupportListener>();

    // 创建第一个Aop代理时,设为true
    /** Set to true when the first AOP proxy has been created */
    private boolean active = false;

    
    // 直接使用的DefaultAopProxyFactory
    public ProxyCreatorSupport() {
        this.aopProxyFactory = new DefaultAopProxyFactory();
    }

    public ProxyCreatorSupport(AopProxyFactory aopProxyFactory) {
        Assert.notNull(aopProxyFactory, "AopProxyFactory must not be null");
        this.aopProxyFactory = aopProxyFactory;
    }

    // 添加监听器
    public void addListener(AdvisedSupportListener listener) {
        Assert.notNull(listener, "AdvisedSupportListener must not be null");
        this.listeners.add(listener);
    }

    // 移除监听器
    public void removeListener(AdvisedSupportListener listener) {
        Assert.notNull(listener, "AdvisedSupportListener must not be null");
        this.listeners.remove(listener);
    }

    // 获取AopProxyFactory工厂
    public AopProxyFactory getAopProxyFactory() {
		return this.aopProxyFactory;
	}

    // 1. 我们可以看到创建代理的时候,就会调用activate()方法,
    // 2. 将Aop代理的创建,交给AopProxyFactory工厂来完成,并将自身作为配置传了进去
    protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            activate();
        }
        return getAopProxyFactory().createAopProxy(this);
    }

    // 触发监听器的回调
    private void activate() {
        // 修改active属性,说明代理已经被创建了
        this.active = true;
        for (AdvisedSupportListener listener : this.listeners) {
            listener.activated(this);
        }
    }

    // 触发监听器的回调
    @Override
    protected void adviceChanged() {
        super.adviceChanged();
        synchronized (this) {
            if (this.active) {
                for (AdvisedSupportListener listener : this.listeners) {
                    listener.adviceChanged(this);
                }
            }
        }
    }

    /**
    * Subclasses can call this to check whether any AOP proxies have been created yet.
    */
    protected final synchronized boolean isActive() {
        return this.active;
    }

}

ProxyFactory

看完上面的类之后,ProxyFactory里面也没多少东西了。

public class ProxyFactory extends ProxyCreatorSupport {

    public ProxyFactory() {
    }

    // 传入目标对象,获取目标对象的所有接口,并设置进去
    public ProxyFactory(Object target) {
        setTarget(target);
        setInterfaces(ClassUtils.getAllInterfaces(target));
    }

    // 手动设置接口
    public ProxyFactory(Class<?>... proxyInterfaces) {
        setInterfaces(proxyInterfaces);
    }

    // 传入代理接口和拦截器,没有目标对象
    //    可以用于让单个的拦截器处理代理对象所有的调用
    public ProxyFactory(Class<?> proxyInterface, Interceptor interceptor) {
        addInterface(proxyInterface);
        addAdvice(interceptor);
    }

    // 为给定的目标对象创建代理,并实现指定的接口
    public ProxyFactory(Class<?> proxyInterface, TargetSource targetSource) {
        addInterface(proxyInterface);
        setTargetSource(targetSource);
    }

    // 使用设定好的配置创建代理
    public Object getProxy() {
        return createAopProxy().getProxy();
    }

    public Object getProxy(ClassLoader classLoader) {
        return createAopProxy().getProxy(classLoader);
    }


    // 传入代理接口和拦截器,没有目标对象
    //    可以用于让单个的拦截器处理代理对象所有的调用
    @SuppressWarnings("unchecked")
    public static <T> T getProxy(Class<T> proxyInterface, Interceptor interceptor) {
        return (T) new ProxyFactory(proxyInterface, interceptor).getProxy();
    }

    public static <T> T getProxy(Class<T> proxyInterface, TargetSource targetSource) {
        return (T) new ProxyFactory(proxyInterface, targetSource).getProxy();
    }

    public static Object getProxy(TargetSource targetSource) {
        if (targetSource.getTargetClass() == null) {
            throw new IllegalArgumentException("Cannot create class proxy for TargetSource "+
                                               "with null target class");
        }
        
        ProxyFactory proxyFactory = new ProxyFactory();
        
        // 设置目标对象(封装到TargetSource中)
        proxyFactory.setTargetSource(targetSource);
        
        // 设置ProxyTargetClass属性
        proxyFactory.setProxyTargetClass(true);
        
        // 调用父类的方法,创建代理
        return proxyFactory.getProxy();
    }

}

DefaultAopProxyFactory

这里会创建两种AopProxy,注意,这里返回的还不是代理,返回的是AopProxy,能够使用AopProxy获取代理,也就是说创建代理的逻辑,存在于AopProxy接口的实现类里面。

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {

        if (   config.isOptimize()          // 是否对生产代理策略使用优化。
            || config.isProxyTargetClass()  // 是否强制使用CGLIB来实现代理
            || hasNoUserSuppliedProxyInterfaces(config)) { // 配置中没有提供接口

            // 获取到目标class (调用this.targetSource.getTargetClass();)
            Class<?> targetClass = config.getTargetClass();

            // 目标class不能为空
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: " +
                                             "Either an interface or a target is required for proxy"+
                                             "creation.");
            }
            
            // 如果targetClass是接口
            //    或者targetClass是jdk动态代理类,
            // 那么使用jdk动态代理
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            
            // 否则使用cglib动态代理方式
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }

    /**
    * Determine whether the supplied {@link AdvisedSupport} has only the
    * {@link org.springframework.aop.SpringProxy} interface specified
    * (or no proxy interfaces specified at all).
    */
    private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
        Class<?>[] ifcs = config.getProxiedInterfaces();
        return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
    }

}

AopProxy

我们从AopProxy接口中可以看到,其中有获取代理的方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WTUVTHqa-1623858305956)(assets/image-20210615221702166.png)]

==getAopProxyFactory().createAopProxy(this);==这句的前半句看完了,接下来看后判断创建代理的逻辑,因为有两个,所以分两个来看,我们看到两个AopProxy的创建都是直接传进去了一个ProxyConfig对象,所以要看下它们的这个构造方法。

Cglib

必须先看懂cglib生成动态代理的一般方式,才能知道为什么这样去设定这些参数。

因此,我们先看懂一个简单的生成cglib的动态代理的示例

CglibTest

1.导入pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zzhua</groupId>
    <artifactId>proxy-dynamic-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
        </dependency>
    </dependencies>

</project>
  1. CallbackBean
public class CallBackBean {

    public CallBackBean() {
        System.out.println("callbackbean cons " + this.getClass());
    }

    public void methodForInterceptor() {
        System.out.println("methodForInterceptor");
        methodB();
    }

    public void methodB() {
        System.out.println("methodB");
    }

    public void methodForNoOp() {
        System.out.println("methodForNoOp");
    }

    public void methodForFixedValue() {
        System.out.println("methodForFixedValue" + this.getClass());
    }

    public void methodForLazyLoader() {
        System.out.println("methodForLazyLoader");
    }

    void methodForDispatcher() {
        System.out.println("methodForDispatcher");
    }
}

3.CglibTest

public class CgLibTest5 {
    public static void main(String[] args) {

        // 第一步:生成代理类的class字节码文件,并加载
        // 第二步:创建代理对象(并调用父类构造方法,初始化)
        // 第三步:调用代理对象的方法(那就要看生成的class字节码文件是什么样的了)

        Enhancer enhancer = new Enhancer();
        enhancer.setCallbacks(
            new Callback[]{
                new Dispatcher() {

                    {
                        System.out.println("构造代码块 => "+this);
                    }

                    @Override
                    public Object loadObject() throws Exception {
                        System.out.println("11111111111" + this);
                        CallBackBean callBackBean = new CallBackBean();
                        return callBackBean;
                    }
                },
                new Dispatcher(){
                    @Override
                    public Object loadObject() throws Exception {
                        System.out.println("222222222" + this);
                        CallBackBean callBackBean = new CallBackBean();
                        return callBackBean;
                    }
                }
            }
        );
        enhancer.setSuperclass(CallBackBean.class);
        enhancer.setCallbackFilter(new CallbackFilter() {
            @Override
            public int accept(Method method) {
                System.out.println("accept...exec【" + method+"】");
                return 0;
            }
        });
        CallBackBean callBackBean = (CallBackBean) enhancer.create();
        System.out.println("============代理对象创建完毕============");
        System.out.println("------------第一次调用代理对象----------");
        callBackBean.methodForDispatcher();
        System.out.println("------------第二次调用代理对象----------");
        callBackBean.methodForDispatcher();

    }
}

4.测试结果

通过查看结果,可以看到cglib生成动态代理的机制

构造代码块 => com.zzhua.cglib4.CgLibTest5$1@506e1b77
accept...exec【void com.zzhua.cglib4.CallBackBean.methodForDispatcher()】
accept...exec【public void com.zzhua.cglib4.CallBackBean.methodForInterceptor()】
accept...exec【public void com.zzhua.cglib4.CallBackBean.methodForLazyLoader()】
accept...exec【public void com.zzhua.cglib4.CallBackBean.methodForFixedValue()】
accept...exec【public void com.zzhua.cglib4.CallBackBean.methodB()】
accept...exec【public void com.zzhua.cglib4.CallBackBean.methodForNoOp()】
accept...exec【protected void java.lang.Object.finalize() throws java.lang.Throwable】
accept...exec【public boolean java.lang.Object.equals(java.lang.Object)】
accept...exec【public java.lang.String java.lang.Object.toString()】
accept...exec【public native int java.lang.Object.hashCode()】
accept...exec【protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException】
callbackbean cons class com.zzhua.cglib4.CallBackBean$$EnhancerByCGLIB$$9504559e
============代理对象创建完毕============
------------第一次调用代理对象----------
11111111111com.zzhua.cglib4.CgLibTest5$1@506e1b77
callbackbean cons class com.zzhua.cglib4.CallBackBean
methodForDispatcher
------------第二次调用代理对象----------
11111111111com.zzhua.cglib4.CgLibTest5$1@506e1b77
callbackbean cons class com.zzhua.cglib4.CallBackBean
methodForDispatcher

CglibAopProxy

class CglibAopProxy implements AopProxy, Serializable {

    // Callback回调的索引
	// Constants for CGLIB callback array indices
	private static final int AOP_PROXY = 0;
	private static final int INVOKE_TARGET = 1;
	private static final int NO_OVERRIDE = 2;
	private static final int DISPATCH_TARGET = 3;
	private static final int DISPATCH_ADVISED = 4;
	private static final int INVOKE_EQUALS = 5;
	private static final int INVOKE_HASHCODE = 6;


    // 代理工厂的配置
	/** The configuration used to configure this proxy */
	protected final AdvisedSupport advised;

    // 构造器参数
	protected Object[] constructorArgs;

    // 构造器参数类型
	protected Class<?>[] constructorArgTypes;

    // Dispatcher是Callback接口的实现类,此回调将方法的调用转移到保存的advised
	/** Dispatcher used for methods on Advised */
	private final transient AdvisedDispatcher advisedDispatcher;

    // 目标类中的每个方法的名字 -> 方法序号
	private transient Map<String, Integer> fixedInterceptorMap;

    // 方法对应的拦截器起始索引(与优化相关)
	private transient int fixedInterceptorOffset;


	// 构造方法
	public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
        
		Assert.notNull(config, "AdvisedSupport must not be null");
        
        // 检查
		if (config.getAdvisors().length == 0 &&    // 没有切面
            config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) { // 没有目标对象
            // 抛出异常
			throw new AopConfigException("No advisors and no TargetSource specified");
		}
        // 赋值
		this.advised = config;
		this.advisedDispatcher = new AdvisedDispatcher(this.advised);
	}

    // 设置创建代理用的构造器参数(必须参数和类型要匹配的上)
	public void setConstructorArguments(Object[] constructorArgs, Class<?>[] constructorArgTypes) {
		if (constructorArgs == null || constructorArgTypes == null) {
			throw new IllegalArgumentException("Both 'constructorArgs' and 'constructorArgTypes' "
                                               +"need to be specified");
		}
		if (constructorArgs.length != constructorArgTypes.length) {
			throw new IllegalArgumentException("Number of 'constructorArgs' (" +constructorArgs.length 
                                               + ") must match number of 'constructorArgTypes' (" +
                                               constructorArgTypes.length + ")");
		}
		this.constructorArgs = constructorArgs;
		this.constructorArgTypes = constructorArgTypes;
	}

	@Override
	public Object getProxy() {
		return getProxy(null);
	}

	@Override
	public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
		}

		try {
            // 获取目标类targetClass(this.targetSource.getTargetClass())
			Class<?> rootClass = this.advised.getTargetClass();
			Assert.state(rootClass != null, "Target class must be available for creating a CGLIB"+ 
                                            "proxy");
			
			Class<?> proxySuperClass = rootClass;
            
            // 看类名是不是包含“$$”,有的话,就是代理类,就是这么简单粗暴
            //                    如果是代理类,就将proxySuperClass设置为代理类的父类,并且添加代理类的所有接口
			if (ClassUtils.isCglibProxyClass(rootClass)) {
				proxySuperClass = rootClass.getSuperclass();
                // 获取代理类的所有接口,并添加到advised中的接口集合中去
				Class<?>[] additionalInterfaces = rootClass.getInterfaces();
				for (Class<?> additionalInterface : additionalInterfaces) {
					this.advised.addInterface(additionalInterface);
				}
			}
			
            // 验证class,并打印log (final方法不能被重写)
			// Validate the class, writing log messages as necessary.
			validateClassIfNecessary(proxySuperClass, classLoader);

			// 开始Cglib的操作了
            
            // 直接new Enhancer(); 
			Enhancer enhancer = createEnhancer();
            
            // 设置类加载器
			if (classLoader != null) {
				enhancer.setClassLoader(classLoader);
				if (classLoader instanceof SmartClassLoader &&
						((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
					enhancer.setUseCache(false);
				}
			}
            
            // 设置父类(目标类)
			enhancer.setSuperclass(proxySuperClass);
            
            // 设置代理的接口,下面AopProxyUtils中详细看
			enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
            
            // 设置命名策略(“BySpringCGLIB”)
			enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
             
			enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

            // 【关键的一步,设置Callback回调数组】
			Callback[] callbacks = getCallbacks(rootClass);
            
            // 使用types数组依次记录Callback回调的类型
			Class<?>[] types = new Class<?>[callbacks.length];
			for (int x = 0; x < types.length; x++) {
				types[x] = callbacks[x].getClass();
			}
            
            // 设置CallbackFilter
			enhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), 
                                       this.fixedInterceptorMap, 
                                       this.fixedInterceptorOffset));
            // 设置回调类型数组
			enhancer.setCallbackTypes(types);

            // 生成代理类并且创建代理对象
			return createProxyClassAndInstance(enhancer, callbacks);
            
		} catch(Exception){
            //...
        }
		
	}

    // 生成代理类并且创建代理对象调用源码
	protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
		enhancer.setInterceptDuringConstruction(false);
		enhancer.setCallbacks(callbacks);
		return (this.constructorArgs != null ?
				enhancer.create(this.constructorArgTypes, this.constructorArgs) :
				enhancer.create());
	}

	protected Enhancer createEnhancer() {
		return new Enhancer();
	}

    // 【 根据目标类获取Callback回调数组 】
	private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
        
        // 代理工厂这些可配置的参数是用来作优化的
		// Parameters used for optimization choices...
		boolean exposeProxy = this.advised.isExposeProxy();
		boolean isFrozen = this.advised.isFrozen();
		boolean isStatic = this.advised.getTargetSource().isStatic();

        // "aop" interceptor 是【AOP_PROXY=0】
		// Choose an "aop" interceptor (used for AOP calls).
		Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

        // 根据exposeProxy配置,决定返回的第二个CallBack【INVOKE_TARGET = 1】
		// Choose a "straight to target" interceptor. (used for calls that are
		// unadvised but can return this). May be required to expose the proxy.
        // exposed和没有exposed的区别在于:
        //          exposed提供的拦截器在intercept方法里面会有放入AopContext的ThreadLocal变量currentProxy中
        // isStatic和不是isStatic的区别在于:
        //          传过去给拦截器的参数是target(原始对象)还是targetSource(包装了target,后面可以改)
		Callback targetInterceptor;
        
		if (exposeProxy) {
			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());
		}

        // 第三个Callback【NO_OVERRIDE = 2;】
		// 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.
        
        // 如果目标对象是static的,并且forzen配置是true,那么就做个优化,看看是怎么优化的?
        //    因为cglib动态代理调用方法一般会匹配到DynamicAdvisedInterceptor这个MethodInterceptor
        //                                    而在这个拦截器里面才做的获取拦截器链的操作
        //    而如果方法对象不变并且切面不变,那么获取到的这个拦截器链的结果肯定是一样的,那么就没必要让
        //    动态代理对象的每次方法调用都去再走一遍获取拦截器链的操作,而是把拦截器链先走一次,然后保存下来,
        //    等下次直接就用,这应该就是所说的优化了(但是需要有前提)
        //    发现新大陆:原来把目标对象包一层是为了能够修改掉目标对象,isForzen又不变,那么我们基本上都不会动这些配置
        //              所以直接把isFrozen设置为true,isStatic也设置为true,就可以提升效率了
        
		if (isStatic && isFrozen) {
            
            // 获取目标类的所有方法
			Method[] methods = rootClass.getMethods();
            
            // 用来保存:目标类中每个方法对应匹配到的Callback  
			Callback[] fixedCallbacks = new Callback[methods.length];
            
            // 用来保存:目标类中的每个方法的名字 -> 方法序号
			this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);

			// TODO: small memory optimization here (can skip creation for methods with no advice)
			for (int x = 0; x < methods.length; x++) {
                
                // 根据方法和目标类,从代理工厂配置类中的切面中获取到拦截器集合(拦截器链)
                //                体会到,获取拦截器链的操作委托给了Advised对象(因为配置都在Advised里,
                //                                                         Advised最清楚)
				List<Object> chain = this.advised
                                            .getInterceptorsAndDynamicInterceptionAdvice(methods[x],
                                                                                         rootClass);
                // 使用每个方法匹配到的拦截器链 创建FixedChainStaticTargetInterceptor回调
				fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(chain,                 
                                                                          this.advised
                                                                                  .getTargetSource()
                                                                                  .getTarget(),
                                                                          this.advised
                                                                                  .getTargetClass());
                // 保存  目标类中的每个方法的名字 -> 方法序号
				this.fixedInterceptorMap.put(methods[x].toString(), 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);
            
            // 将fixedInterceptorOffset下角标定位到callbacks中刚刚创建的方法对应的拦截器上起始索引处
			this.fixedInterceptorOffset = mainCallbacks.length;
		}
		else {
			callbacks = mainCallbacks;
		}
		return callbacks;
	}


	@Override
	public boolean equals(Object other) {
		return (this == other || (other instanceof CglibAopProxy &&
				AopProxyUtils.equalsInProxy(this.advised, ((CglibAopProxy) other).advised)));
	}

	@Override
	public int hashCode() {
		return CglibAopProxy.class.hashCode() * 13 + this.advised.getTargetSource().hashCode();
	}

	/**
	 * Process a return value. Wraps a return of {@code this} if necessary to be the
	 * {@code proxy} and also verifies that {@code null} is not returned as a primitive.
	 */
	private static Object processReturnType(Object proxy, 
                                            Object target, 
                                            Method method, 
                                            Object retVal) {
        
        // 如果返回了target,那么就将返回值改为proxy
		// Massage return value if necessary
		if (retVal != null && 
            retVal == target &&
            !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
			// Special case: it returned "this". Note that we can't help
			// if the target sets a reference to itself in another returned object.
            
			retVal = proxy; 
		}
        
        // 获取方法的返回类型
		Class<?> returnType = method.getReturnType();
        
        // 如果方法的返回类型不是void,并且返回类型是java基本数据类型,返回值是null,那么抛出aop调用异常
		if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
			throw new AopInvocationException(
					"Null return value from advice does not match primitive return type for: " 
                    + method);
		}
        // 返回retVal
		return retVal;
	}
AopProxyUtils
public abstract class AopProxyUtils {

    // 获取所有配置的接口
    static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
        
        // 获取代理工厂中的interfaces属性
        Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
        
        // 如果代理工厂中的interfaces属性没有配置过接口
        if (specifiedInterfaces.length == 0) {
            
            // 获取目标类targetClass(目标对象的类)
            Class<?> targetClass = advised.getTargetClass();
            
            if (targetClass != null) {
                
                // 如果targetClass是接口,那就直接设置给advised
                if (targetClass.isInterface()) {
                    advised.setInterfaces(targetClass);
                }
                
                // 如果是targetClass是jdk动态代理类
                else if (Proxy.isProxyClass(targetClass)) {
                    advised.setInterfaces(targetClass.getInterfaces());
                }
                // 重新指定给specifiedInterfaces
                specifiedInterfaces = advised.getProxiedInterfaces();
            }
        }
        
        // 如果代理工厂中的interfaces属性中没有包括SpringProxy接口(只是个标记接口),那就要添加它
        boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
        
        // 看到了opaque的配置起作用的地方了
        //     如果opaque属性是true,那么就不会添加Advised接口
        boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
        
        // 如果decoratingProxy是false,那就不添加DecoratingProxy接口
        boolean addDecoratingProxy = 
                        (decoratingProxy && !advised.isInterfaceProxied( DecoratingProxy.class));
        
        // 非 用户指定的接口 数量
        int nonUserIfcCount = 0;
        
        if (addSpringProxy) {
            nonUserIfcCount++;
        }
        if (addAdvised) {
            nonUserIfcCount++;
        }
        if (addDecoratingProxy) {
            nonUserIfcCount++;
        }
        
        // 添加这几个接口进去
        
        Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
        
        // 拷贝接口数组
        System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
        
        int index = specifiedInterfaces.length;
        if (addSpringProxy) {
            proxiedInterfaces[index] = SpringProxy.class;
            index++;
        }
        if (addAdvised) {
            proxiedInterfaces[index] = Advised.class;
            index++;
        }
        if (addDecoratingProxy) {
            proxiedInterfaces[index] = DecoratingProxy.class;
        }
        
        // 返回最终的接口数组
        return proxiedInterfaces;
    }
}
ProxyCallbackFilter

我们来看这句:

enhancer.setCallbackFilter(new ProxyCallbackFilter(
                                this.advised.getConfigurationOnlyCopy(),  // 不能给引用,所以给拷贝
                                this.fixedInterceptorMap,    // 方法名字->方法数组索引(优化相关) 
                                this.fixedInterceptorOffset) // 从方法对应的拦截器索引开始(优化相关)
                           );

用来决定Cglib动态代理类的重写方法调用;上面getCallbacks(Class<?>方法中提到的优化,也必须要这个CallbackFilter支持它。

/**
 * CallbackFilter to assign Callbacks to methods.
 */
private static class ProxyCallbackFilter implements CallbackFilter {

    // 代理工厂的配置
    private final AdvisedSupport advised;

    // 方法名字->方法数组索引
    private final Map<String, Integer> fixedInterceptorMap;

     // 从方法对应的拦截器索引开始
    private final int fixedInterceptorOffset;

    public ProxyCallbackFilter(AdvisedSupport advised, 
                               Map<String, Integer> fixedInterceptorMap, 
                               int fixedInterceptorOffset) {
        this.advised = advised;
        this.fixedInterceptorMap = fixedInterceptorMap;
        this.fixedInterceptorOffset = fixedInterceptorOffset;
    }

    
    /*
      这里需要先看下对应情况:
            【0】【AOP_PROXY】           DynamicAdvisedInterceptor    
            【1】【INVOKE_TARGET】       Dynamic/Static Unadvised[Exposed]Interceptor
            【2】【NO_OVERRIDE】         SerializableNoOp   直接调用父类方法,不做修改
            【3】【DISPATCH_TARGET】     StaticDispatcher   直接把方法调用转发给目标对象去调用
            【4】【DISPATCH_ADVISED】    AdvisedDispatcher  
            【5】【INVOKE_EQUALS】       EqualsInterceptor  与代理对象比较地址
            【6】【INVOKE_HASHCODE】     HashCodeInterceptor targetSource的哈希码+CglibAopProxy的哈希码
    */
    @Override
    public int accept(Method method) {

        // 如果是finalize方法,那么不做修改,直接调用原父类的方法
        if (AopUtils.isFinalizeMethod(method)) {
            logger.debug("Found finalize() method - using NO_OVERRIDE");
            return NO_OVERRIDE; // 【2】
        }
        // 如果方法在Advised接口中声明,并且opaque属性是否则,那么回调类型是 StaticDispatcher,
        //                                                          直接把方法调用转发给目标对象去调用
        if (!this.advised.isOpaque() && method.getDeclaringClass().isInterface() &&
            method.getDeclaringClass().isAssignableFrom(Advised.class)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Method is declared on Advised interface: " + method);
            }
            return DISPATCH_ADVISED; // 【4】
        }
        
        // 如果是equals方法,方法参数先与代理对象比较地址,
        //                 如果一样,则返回true
        //                 如果不一样,再看是不是Factory类型,
        //                               如果不是,返回false
        //                               如果是,再强转为EqualsInterceptor,比较里面的advised属性
        //                                      (不能强转则false)
        // We must always proxy equals, to direct calls to this.
        if (AopUtils.isEqualsMethod(method)) {
            logger.debug("Found 'equals' method: " + method);
            return INVOKE_EQUALS; // 【5】
        }
        
        // 返回:CglibAopProxy.class.hashCode() * 13 + this.advised.getTargetSource().hashCode();
        // We must always calculate hashCode based on the proxy.
        if (AopUtils.isHashCodeMethod(method)) {
            logger.debug("Found 'hashCode' method: " + method);
            return INVOKE_HASHCODE; // 【6】
        }
        
        // 获取目标类
        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) {
            
            // 如果暴露代理,那么走 DynamicAdvisedInterceptor
            if (exposeProxy) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Must expose proxy on advised method: " + method);
                }
                return AOP_PROXY; // 【0】
            }
            
            String key = method.toString();
            
            // 因为只有isStatic和isFrozen开启的时候,才会添加方法固定的拦截器
            // 如果有,那就用之前已经缓存起来的拦截器
            if (isStatic && isFrozen && this.fixedInterceptorMap.containsKey(key)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("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); // 【index + this.fixedInterceptorOffset】
            }
            // 否则用 DynamicAdvisedInterceptor
            else {
                if (logger.isDebugEnabled()) {
                    logger.debug("Unable to apply any optimizations to advised method: " + method);
                }
                return AOP_PROXY; // 【0】
            }
        }
        
        // 如果没有增强,并且没有冻结配置
        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.
            
            // 如果暴露代理 或者 目标对象可变 则使用 Dynamic/Static Unadvised[Exposed]Interceptor
            if (exposeProxy || !isStatic) {
                return INVOKE_TARGET; // 【1】
            }
            
            // 方法的返回类型
            Class<?> returnType = method.getReturnType();
            
            // 以上条件不满足,如果方法的返回类型是目标类
            if (returnType.isAssignableFrom(targetClass)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Method return type is assignable from target type and " +
                                 "may therefore return 'this' - using INVOKE_TARGET: " + method);
                }
                return INVOKE_TARGET; // 【1】 
            }    
            else {
                if (logger.isDebugEnabled()) {
                    logger.debug("Method return type ensures 'this' cannot be returned - " +
                                 "using DISPATCH_TARGET: " + method);
                }
                // StaticDispatcher
                return DISPATCH_TARGET; // 【3】
            }
        }
    }
}
Callback类型

cglib提供了其它6种回调类型:【NoOp、LazyLoader、Dispatcher、InvocationHandler、FixedValue

对于不同的回调类型,cglib对父类方法的重写策略也是不一样的。

上面提到了很多的MethodInterceptor类型的Callback,我们列出来在下面,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AJdMQM9I-1623858305957)(assets/image-20210616100427727.png)]

enhancer.create()

当enhancer都配置好了之后,调用enhancer.create(),就能够生成代理类并且创建代理对象。

这样对代理对象的方法的调用,就能够按照我们配置好的逻辑走下去。

DynamicAdvisedInterceptor

既然代理对象已经创建好了,那么接下来就是看代理对象是如何按照我们的设置,调用方法的,从而理清楚整个调用流程。

我们来看测试中的这一句:

int result = caculator.calculate(4, 0,"zzhua");

为什么要找下面这个方法?!很多教程都没讲到,其实已经说过了,前面有说的ProxyCallbackFilter就是来定义重写的不同方法,进到不同的callback,按照ProxyCallbackFilter就是进的这个callback。

/**
 * General purpose AOP callback. Used when the target is dynamic or when the
 * proxy is not frozen.
 */
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {

    // 保存了代理工厂的配置
    private final AdvisedSupport advised;

    // 唯一构造
    public DynamicAdvisedInterceptor(AdvisedSupport advised) {
        this.advised = advised;
    }

    @Override
    public Object intercept(Object proxy,    // 代理对象
                            Method method,   // 调用的方法对象
                            Object[] args,   // 传过来的参数
                            MethodProxy methodProxy)  // 与fastClass机制有关
    {
        
        // 上下文中之前的代理
        Object oldProxy = null;
        
        // 是否将代理对象保存到AopContext#currentProxy(ThreadLocal)
        boolean setProxyContext = false;
        
        // 目标类
        Class<?> targetClass = null;
        
        // 目标对象
        Object target = null;
        
        try {
            // 如果exposeProxy为true
            if (this.advised.exposeProxy) {
                
                // 将代理对象暴露出去
                oldProxy = AopContext.setCurrentProxy(proxy);
                setProxyContext = true;
            }
            
            // 从targetsource中获取target
            target = getTarget();
            if (target != null) {
                targetClass = target.getClass();
            }
            
            // 根据方法和目标类class,使用代理工厂配置获取拦截器链,
            //                        代理工厂配置把这件事情委托给了 DefaultAdvisorChainFactory,
            //                                  然后外加做了个缓存
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method,
                                                                                          targetClass);
            Object retVal;
            
            // 如果没有拦截器链并且方法是public的
            if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
                // 适配参数
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                
                // 那就直接使用反射调用目标对象的目标方法
                retVal = methodProxy.invoke(target, argsToUse);
            }
            else {
                
                // 看到主角了,创建方法调用MethodInvocation对象,并且调用它的proceed()方法
                // We need to create a method invocation...
                retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, 
                                                   chain, methodProxy)
                             .proceed();
                
            }
            // 处理返回值类型
            retVal = processReturnType(proxy, target, method, retVal);
            // 返回结果
            return retVal;
        }
        finally {
            if (target != null) {
                releaseTarget(target);
            }
            if (setProxyContext) {
                // Restore old proxy.
                AopContext.setCurrentProxy(oldProxy); // 可以学下这种
            }
        }
    }
}
CglibMethodInvocation
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {

    private final MethodProxy methodProxy;

    private final boolean publicMethod;

    public CglibMethodInvocation(Object proxy, 
                                 Object target,
                                 Method method, 
                                 Object[] arguments,
                                 Class<?> targetClass, 
                                 List<Object> interceptorsAndDynamicMethodMatchers, 
                                 MethodProxy methodProxy) 
    {

        super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
        this.methodProxy = methodProxy;
        this.publicMethod = Modifier.isPublic(method.getModifiers());
    }


    @Override
    protected Object invokeJoinpoint() throws Throwable {
        // public方法使用cglib提供的fastClass机制去调用,这样速度更快
        if (this.publicMethod) {
            return this.methodProxy.invoke(this.target, this.arguments);
        }
        else {
            // 如果不是public方法,那么就使用暴力反射去调用
            return super.invokeJoinpoint();
        }
    }
}
ReflectiveMethodInvocation

主要的逻辑还是在ReflectiveMethodInvocation,这里面使用了责任链模式,类似于Tomcat里面的Filter使用的责任链模式。

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {

	// 代理对象
    protected final Object proxy;

    // 目标对象
    protected final Object target;

    // 调用的方法
    protected final Method method;

    // 传递的参数
    protected Object[] arguments;

    // 目标类
    private final Class<?> targetClass;

    // 和这次调用相关的用户信息
    private Map<String, Object> userAttributes;

    // 和这次调用相关的拦截器集合
    protected final List<?> interceptorsAndDynamicMethodMatchers;

    // 索引从 -1 开始
    private int currentInterceptorIndex = -1;

    protected ReflectiveMethodInvocation(
        Object proxy, Object target, Method method, Object[] arguments,
        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 getThis() {
        return this.target;
    }

    @Override
    public final AccessibleObject getStaticPart() {
        return this.method;
    }

    @Override
    public final Object[] getArguments() {
        return (this.arguments != null ? this.arguments : new Object[0]);
    }

    //【核心方法】
    //   1. InterceptorAndDynamicMethodMatcher里面包含MethodInterceptor,
    //                                        而且包含MethodMatcher,可以做动态匹配
    //   2. 如果不是InterceptorAndDynamicMethodMatcher,
    //         那么就必须是实现了MethodInterceptor接口的对象
    
    @Override
    public Object proceed() throws Throwable {
        
        // 定义责任链的出口:当 当前拦截器的索引 == 最后一个拦截器的索引时(说明最后一个拦截器已经执行了)
        //                 调用目标方法,然后逐层返回
        // We start with an index of -1 and increment early.
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();
        }

        // 获取到下一个拦截器,并且将当前拦截器索引 +1
        Object interceptorOrInterceptionAdvice =
            this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        
        // 如果拦截器类型是 InterceptorAndDynamicMethodMatcher接口 类型的,
        //                         此接口封装了【MethodInterceptor】和【MethodMatcher】
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            
            // 强转
            InterceptorAndDynamicMethodMatcher dm =
                (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
            
            // 使用MethodMatcher去匹配
            if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
                // 使用里面的拦截器去调用
                return dm.interceptor.invoke(this);
            }
            else {
                // 动态匹配失败,则继续调用责任链的下一个拦截器
                // Dynamic matching failed.
                // Skip this interceptor and invoke the next in the chain.
                return proceed();
            }
        }
        else {
            
            // 如果直接是MethodInterceptor接口,那就强转直接调用就好了
            
            // It's an interceptor, so we just invoke it: The pointcut will have
            // been evaluated statically before this object was constructed.
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }

    // 反射调用
    protected Object invokeJoinpoint() throws Throwable {
        return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
    }


    // 将当前的调用克隆一份出来。
    
    @Override
    public MethodInvocation invocableClone() {
        Object[] cloneArguments = null;
        if (this.arguments != null) {
            // Build an independent copy of the arguments array.
            cloneArguments = new Object[this.arguments.length];
            System.arraycopy(this.arguments, 0, cloneArguments, 0, this.arguments.length);
        }
        return invocableClone(cloneArguments);
    }

    @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<String, Object>();
        }

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

}

关键点提示

关键点在上面都详细的注释了,但是为了方便查阅,用debug的方式查看详细信息

关键点一:AspectJ注解如何封装成Advisor

BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors 方法扫描spring容器中的@Aspect注解的bean,并将该bean的class中方法上的标注AsepectJ注解的增强方法,封装为切面。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q4yRxuyd-1623858305957)(assets/image-20210616163522016.png)]

关键点二:如何从所有切面中筛选适合于当前bean的切面

使用了工具类的静态方法筛选:AopUtils.findAdvisorsThatCanApply(List,Class<?>)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TZlyfNx0-1623858305958)(assets/image-20210616170854817.png)]

关键点三:自动代理创建器获取的Advisor何时跑到ProxyFactory中的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aTQx90Bz-1623858305958)(assets/image-20210616170316183.png)]

关键点四:切面在代理对象调用方法时是如何转为MethodInterceptor的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I88CP6Ll-1623858305959)(assets/image-20210616173944981.png)]

关键点五:责任链是如何控制代理对象拦截器调用的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-trgOEHZw-1623858305959)(assets/image-20210616193507775.png)]

责任链调用流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TpC9BzGp-1623858305960)(assets/image-20210616194150095.png)]

关键点六:增强是如何调用到切面这个bean的方法的

我们知道AspectJ支持5种,其中有两种需要适配。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4R9EBAjI-1623858305960)(assets/image-20210615180427291.png)]

大部分的功能都集中在AbstractAspectJAdvice中有实现。并且这种抽象类里面维护了一个变量AspectInstanceFactory

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1zBNnmuu-1623858305961)(assets/image-20210616204103081.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DxHE6wQS-1623858305962)(assets/image-20210616233413837.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n6CJOIan-1623858305962)(assets/image-20210616233436758.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sstLvkAi-1623858305963)(assets/image-20210616233459617.png)]

Spring Aop流程概览

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sbcrskL3-1623858305963)(assets/Spring Aop.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PlLORJkI-1623858305964)(assets/image-20210616160239845.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g3X4bDfk-1623858305964)(assets/image-20210616160416255.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qHdTdKVR-1623858305965)(assets/image-20210616161300896.png)]

这篇关于Spring Aop源码流程分析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!