spring aop
大约 63 分钟
spring aop
概述
Advisor是啥
在Spring框架中,Advisor
(顾问)是用于定义切面(Aspect)的一种机制。Advisor
包含切点(Pointcut)和增强(Advice),它可以指导在何处以及如何应用特定的行为。
在AOP(面向切面编程)中,Advisor
帮助将横切关注点(cross-cutting concerns)从主要业务逻辑中分离出来。
具体而言,Advisor
通常有两个主要实现:
- Pointcut Advisor(切点顾问): 定义了切点,即指定在何处应用增强的规则。
- Introduction Advisor(引介顾问): 允许向现有的类引介新的接口和属性。
Advisor
的目标是通过提供一种非侵入性的方式,将横切关注点集中在一个地方,并将其应用于应用程序的多个部分。这有助于提高代码的可维护性和可重用性。
@Around、@Before、@After、@AfterReturning、@AfterThrowing
会被解析成 PointcutAdvisor
DeclareParents
会被解析成 IntroductionAdvisor
PointcutAdvisor 和 IntroductionAdvisor 的区别
在进行切入点匹配时:
- PointcutAdvisor:使用其Poincut属性,进行ClassFilter+MethodMatcher
- IntroductionAdvisor:进行ClassFilter
在创建代理对象时:
- PointcutAdvisor:会获取其Advice属性,转换成MethodInterceptor对象,组成InterceptorChain,在执行代理对象的方法时,会执行与方法匹配的Interceptors
- IntroductionAdvisor:
- 会拿到其 interfaces 设置为代理对象的接口,然后创建代理对象,所以创建出来的代理对象可以强转成对应的接口,从而实现 不修改被代理的情况下新增方法。
- 和PointcutAdvisor一样。会获取其Advice属性,转换成MethodInterceptor对象,组成InterceptorChain,在执行代理对象的方法时,会执行与方法匹配的Interceptors
@EnableAspectJAutoProxy
/**
*
* 1. 使用注解 {@code @EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)} {@link EnableAspectJAutoProxy}
* 该注解会导入 {@code @Import(AspectJAutoProxyRegistrar.class)} {@link AspectJAutoProxyRegistrar}
*
* 2. 所以会在解析配置类阶段,回调 {@link AspectJAutoProxyRegistrar#registerBeanDefinitions(AnnotationMetadata, BeanDefinitionRegistry)} 来注册bean
*
* 3. 会执行 {@link AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry)} 注册bean
* 就是注册这个 {@link AnnotationAwareAspectJAutoProxyCreator}
*
* 4. 将注解的属性值,设置到BeanDefinition中,当bean进行属性填充的设置会设置到bean的属性属性中。
* proxyTargetClass,决定是否使用cglib代理 -> {@link AopConfigUtils#forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry)}
* exposeProxy,在执行 MethodInterceptor时是否将代理对象存到ThreadLocal中 -> {@link AopConfigUtils#forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry)}
* */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
/**
* 这个参数是用来约束是cglib代理或者jdk代理的,但不是强执约束,会优先判断是否符合cglib代理的条件。
* true:建议cglib代理。
* false:建议jdk代理。
*/
boolean proxyTargetClass() default false;
/**
* 在执行 代理对象的方法前,是否将代理对象缓存到 ThreadLocal 中。
* true:缓存
* false:不缓存
*
* @since 4.3.1
*/
boolean exposeProxy() default false;
}
AnnotationAwareAspectJAutoProxyCreator的实例化
AnnotationAwareAspectJAutoProxyCreator 实现了 SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware。
在实例化后,初始化前会回调 {@link BeanFactoryAware#setBeanFactory(BeanFactory)}
AnnotationAwareAspectJAutoProxyCreator 后置处理器回调
实例化前阶段
/**
* AnnotationAwareAspectJAutoProxyCreator 没有重写方法,所以执行父类的{@link AbstractAutoProxyCreator#postProcessBeforeInstantiation(Class, String)}
*
* 1. beanName是空 或者 targetSourcedBeans(已AOP代理对象集合)属性没有记录过该beanName
* - advisedBeans(增强bean集合) 中记录了,就 return null
* - 是基础bean {@link AnnotationAwareAspectJAutoProxyCreator#isInfrastructureClass(Class)} 或者 应该跳过 {@link AspectJAwareAdvisorAutoProxyCreator#shouldSkip(Class, String)}
* 记录一下 `this.advisedBeans.put(cacheKey, Boolean.FALSE);`
* return null
*
* 2. 生成 TargetSource {@link AbstractAutoProxyCreator#getCustomTargetSource(Class, String)}
* 需要设置 TargetSourceCreator 属性 {@link AbstractAutoProxyCreator#setCustomTargetSourceCreators(TargetSourceCreator...)} 才会有用,
* 但是看源码没有用到,所以这个方法一直返回null
*
* 3. TargetSource 不为null
* - 记录targetSourcedBeans(被代理对象集合) `this.targetSourcedBeans.add(beanName);`
* - 得到这个bean匹配的advice和advisor集合 {@link AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean(Class, String, TargetSource)}
* - 创建代理对象 {@link AbstractAutoProxyCreator#createProxy(Class, String, Object[], TargetSource)}
* - 记录AOP代理对象 `this.proxyTypes.put(cacheKey, proxy.getClass());`
* - 返回生成的代理对象
* */
提前AOP阶段
/**
*
* AnnotationAwareAspectJAutoProxyCreator 没有重写方法,所以执行父类的 {@link AbstractAutoProxyCreator#getEarlyBeanReference(Object, String)}
*
* 1. 记录提前代理引用集合 `this.earlyProxyReferences.put(cacheKey, bean);`
* 2. 需要就创建代理对象 {@link AbstractAutoProxyCreator#wrapIfNecessary(Object, String, Object)}
* */
初始化后阶段
/**
* AnnotationAwareAspectJAutoProxyCreator 没有重写方法,所以执行父类的 {@link AbstractAutoProxyCreator#postProcessAfterInitialization(Object, String)}
*
* 1. earlyProxyReferences(提前代理引用集合) 中没有这个 bean
* 2. 需要就创建代理对象 {@link AbstractAutoProxyCreator#wrapIfNecessary(Object, String, Object)}
* */
总结
- Spring Aop中切面、切点、通知对应到Advisor、Pointcut、Advice。
- @EnableAspectJAutoProxy注解会import到容器中AspectJAutoProxyRegistrar最终注册AnnotationAwareAspectJAutoProxyCreator。
- AnnotationAwareAspectJAutoProxyCreator继承了SmartInstantiationAwareBeanPostProcessor,会在实例化前、提前aop、初始化后三个阶段尝试创建代理。
- AnnotationAwareAspectJAutoProxyCreator中会获取容器中Advisor类型的Bean以及加了@Aspect注解的Bean。然后通过匹配是否适用于当前Bean。
- 创建代理(两种方式)。
- 执行拦截器链的逻辑。
AOP切面的解析
实例化前后置
/**
* 在Bean创建的生命周期会回调该方法,如果返回值不是null,
* 会执行 {@link BeanPostProcessor#postProcessAfterInitialization(Object, String)}
* 然后直接返回bean,不会进行后续bean生命周期的执行
*
* @param beanClass 要实例化的 Bean 的类
* @param beanName Bean 的名称
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
// 获取key
Object cacheKey = getCacheKey(beanClass, beanName);
// beanName是空 或者 targetSourcedBeans(已AOP代理对象集合)中没有记录beanName
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
// advisedBeans(增强bean集合) 中记录了,就返回null
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
/**
* 是基础设置类 或者 应该跳过 就返回null
*
* isInfrastructureClass:是这些 Advice、Pointcut、Advisor、AopInfrastructureBean 类型的子类
* shouldSkip {@link AutoProxyUtils#isOriginalInstance(String, Class)}
* beanName是空 或者 beanName的长度不等于 类全名+.ORIGINAL ---> false
* 类全名开头 且 结尾是.ORIGINAL ---> true
*
* 什么情况会设置这个 .ORIGINAL ???
* */
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
// 记录在 advisedBeans(增强bean集合) 中
/**
* false 表示这个bean 是 advisor 相关的bean
* */
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
/**
* {@link AbstractAutoProxyCreator#customTargetSourceCreators} 属性不为null,就遍历 {@link TargetSourceCreator}
* 执行 {@link TargetSourceCreator#getTargetSource(Class, String)} 创建 TargetSource,返回值是null就直接return。
*
* 在这里使用 TargetSourceCreator 来创建代理对象也可以实现@Lazy的效果,即延时bean的创建,
* 因为这里直接返回了 代理对象,而执行代理对象在执行方法时会执行 {@link TargetSource#getTarget()} 拿到被代理对象,一般在这个方法就是 getBean 从而
* 可以实现延时bean的实例化
*
* 注:TargetSource 封装了被代理对象,然后aop是对TargetSource进行代理
* */
// 如果我们有一个自定义的 TargetSource,请在此处创建代理。
// 禁止对目标 Bean 进行不必要的缺省实例化:TargetSource 将以自定义方式处理目标实例。
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
// 有beanName
if (StringUtils.hasLength(beanName)) {
// 记录在 targetSourcedBeans(被代理对象集合) 中
this.targetSourcedBeans.add(beanName);
}
/**
* {@link AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean(Class, String, TargetSource)}
* 1. 会将容器中所有的 Advisor 都进行实例化,缓存起来。
* 2. 按照 类匹配 或者 (类匹配+AspectJ表达式匹配)
* 3. 返回满足条件的 Advisor
* */
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
/**
* 创建代理对象
* */
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
// 返回创建好的代理对象,这里返回值不是null,所以会中断后续Bean的声明周期,也就是后面的填充bean、初始化等等操作都不会执行了
return proxy;
}
return null;
}
是基础类型
@Override
protected boolean isInfrastructureClass(Class<?> beanClass) {
// Previously we setProxyTargetClass(true) in the constructor, but that has too
// broad an impact. Instead we now override isInfrastructureClass to avoid proxying
// aspects. I'm not entirely happy with that as there is no good reason not
// to advise aspects, except that it causes advice invocation to go through a
// proxy, and if the aspect implements e.g the Ordered interface it will be
// proxied by that interface and fail at runtime as the advice method is not
// defined on the interface. We could potentially relax the restriction about
// not advising aspects in the future.
return (super.isInfrastructureClass(beanClass) || (this.aspectJAdvisorFactory != null
&& this.aspectJAdvisorFactory.isAspect(beanClass)));
}
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;
}
应该跳过
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 查找并创建容器中所有Advisor类型的Bean同时拿到BeanFactory中标注了@Aspect 的bean
// 将标注了 @Around、@Before、@After、@AfterReturning、@AfterThrowing 的方法解析成 InstantiationModelAwarePointcutAdvisorImpl
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
// 当前beanName是advisor中的一个
if (advisor instanceof AspectJPointcutAdvisor && ((AspectJPointcutAdvisor) advisor).getAspectName()
.equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
查找所有Advisor
/**
* 查找容器中advisor类型的bean,
* 同时将BeanFactor中标注了@Around、@Before、@After、@AfterReturning、@AfterThrowing
* 的方法解析成 InstantiationModelAwarePointcutAdvisorImpl
*/
@Override
protected List<Advisor> findCandidateAdvisors() {
// 这个逻辑其实很简单,就是拿到容器中 Advisor 类型的bean,然后创建,然后把这些bean返回
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
/**
* 拿到BeanFactory中标注了@Aspect 的bean
* 将标注了 @Around、@Before、@After、@AfterReturning、@AfterThrowing 的方法解析成 InstantiationModelAwarePointcutAdvisorImpl
* */
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
查找容器中所有Advisor类型的Bean
AbstractAdvisorAutoProxyCreator:
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
// 在bean工厂中找到所有的advisor类型的bean并创建
return this.advisorRetrievalHelper.findAdvisorBeans();
}
BeanFactoryAdvisorRetrievalHelper:
/**
* 在当前 bean 工厂中查找所有符合条件的 Advisor bean,
* 忽略 FactoryBeans 并排除当前正在创建的 bean。
*
* @return the list of {@link org.springframework.aop.Advisor} beans
* @see #isEligibleBean
*/
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
/**
* 就是从 BeanFactory 中找出 Advisor 类型的bean,这些bean不会执行初始化,而是直接从BeanDefinitionMap中找到然后返回而已
* */
// 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 ArrayList<>();
}
// 提前创建所有的 advisorNames,记录在advisors,然后返回advisors
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
/**
* Spring AOP 没有重写也就是返回 ture AnnotationAwareAspectJAutoProxyCreator
*
* {@link AbstractAdvisorAutoProxyCreator.BeanFactoryAdvisorRetrievalHelperAdapter#isEligibleBean(String)}
* {@link DefaultAdvisorAutoProxyCreator#isEligibleAdvisorBean(String)}
*
* {@link InfrastructureAdvisorAutoProxyCreator#isEligibleAdvisorBean(String)}
* @EnableTransactionManagement 使用的就是这个。逻辑就是 BeanDefinitionMap中有BeanDefinition && Role得是这个值 {@link BeanDefinition#ROLE_INFRASTRUCTURE}
* */
if (isEligibleBean(name)) {
// 跳过真正创建的
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
} else {
try {
// 创建bean
advisors.add(this.beanFactory.getBean(name, Advisor.class));
} catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping advisor '" + name
+ "' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
解析@Aspect 的Bean
BeanFactoryAspectJAdvisorsBuilder:
/**
* 拿到BeanFactory中标注了@Aspect 的bean
* 将标注了 @Around、@Before、@After、@AfterReturning、@AfterThrowing 的方法解析成 InstantiationModelAwarePointcutAdvisorImpl
* <p>
* Look for AspectJ-annotated aspect beans in the current bean factory,
* and return to a list of Spring AOP Advisors representing them.
* <p>Creates a Spring Advisor for each AspectJ advice method.
*
* @return the list of {@link org.springframework.aop.Advisor} beans
* @see #isEligibleBean
*/
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
//缓存字段aspectNames没有值 注意实例化第一个单实例bean的时候就会触发解析切面
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
/**
* 就是 beanName 是否符合正则匹配规则 {@link AnnotationAwareAspectJAutoProxyCreator#isEligibleAspectBean(String)}
* 会判断这个属性 {@link AnnotationAwareAspectJAutoProxyCreator#includePatterns} 是否为空,为空就直接返回true,不为空就遍历属性 进行正则匹配,匹配了才返回true
*
* 属性默认值就是null,所有 这里一直返回true
* */
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
Class<?> beanType = this.beanFactory.getType(beanName, false);
if (beanType == null) {
continue;
}
// 进行 Aspect 判断
/**
* advisorFactory 是 ReflectiveAspectJAdvisorFactory
* 有 @Aspect 的类 就是 true
* */
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
// 如果是 @Aspect("") 这样子使用,就满足if
if (amd.getAjType()
.getPerClause()
.getKind() == PerClauseKind.SINGLETON) {
// 这个也是有用的,后面排序Advisor的时候 是根据@Aspect这个切面类来排序的
MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
/**
* 处理有 @Aspect 的类
* 然后将类里面 @Around、@Before、@After、@AfterReturning、@AfterThrowing 的方法解析成 InstantiationModelAwarePointcutAdvisorImpl
* 另外还会根 据需要 添加 SyntheticInstantiationAdvisor、DeclareParentsAdvisor 的 advisor
* */
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
// 缓存起来。这个是可以直接返回的
this.advisorsCache.put(beanName, classAdvisors);
} else {
// 缓存起来。这个是后面还得重新创建 `this.advisorFactory.getAdvisors(factory))`
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
} else {
// 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");
}
// 这个也是有用的,后面排序Advisor的时候 是根据@Aspect这个切面类来排序的
MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
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;
}
@Override
public boolean isAspect(Class<?> clazz) {
/**
* 有@Aspect 注解 且不是 AspectJ language 的语法
*
* 说人话就是 有@Aspect注解就行
* */
return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
}
ReflectiveAspectJAdvisorFactory:
/**
* 处理有 @Aspect 的类
* 然后将类里面 Around、Before、After、AfterReturning、AfterThrowing 的方法解析成 InstantiationModelAwarePointcutAdvisorImpl
* 另外还会根据需要 添加 SyntheticInstantiationAdvisor、DeclareParentsAdvisor 的 advisor
*
* @param aspectInstanceFactory the aspect instance factory
* (not the aspect instance itself in order to avoid eager instantiation)
* @return
*/
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
/**
* @Aspect
* class A{}
* @Component
* class B extends A{}
*
* aspectClass 是 A.class
* aspectName 是 b
* */
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata()
.getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata()
.getAspectName();
// 校验一下,简单来说就是类得有 @Aspect 注解
validate(aspectClass);
// 记录当前切面类的元数据。后面排序Advisor的时候 是根据@Aspect这个切面类来排序的
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
/**
* 拿到 aspectClass 中 除了 @Pointcut 注解的方法,按照 Around、Before、After、AfterReturning、AfterThrowing 进行排序
* */
for (Method method : getAdvisorMethods(aspectClass)) {
/**
* 标注了 Pointcut、Around、Before、After、AfterReturning、AfterThrowing 注解的方法不会返回 null
* 但是因为 遍历的method 是不包含 @Pointcut 的,所以只是将 Around、Before、After、AfterReturning、AfterThrowing 解析成 Advisor
*
* 返回的是是这个实现类 InstantiationModelAwarePointcutAdvisorImpl
* */
// Prior to Spring Framework 5.2.7, advisors.size() was supplied as the declarationOrderInAspect
// to getAdvisor(...) to represent the "current position" in the declared methods list.
// However, since Java 7 the "current position" is not valid since the JDK no longer
// returns declared methods in the order in which they are declared in the source code.
// Thus, we now hard code the declarationOrderInAspect to 0 for all advice methods
// discovered via reflection in order to support reliable advice ordering across JVM launches.
// Specifically, a value of 0 aligns with the default value used in
// AspectJPrecedenceComparator.getAspectDeclarationOrder(Advisor).
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
// 如果是每个目标方面,则发出虚拟实例化方面。
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata()
.isLazilyInstantiated()) {
// TODOHAITAO: 2022/10/3 这是干啥用的,但是 @Aspect 是不会满足这个条件的
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// 查找引入的字段。
// Find introduction fields.
for (Field field : aspectClass.getDeclaredFields()) {
/**
* 就是字段上有这个 @DeclareParents(value="",defaultImpl=A.class) 会解析成 DeclareParentsAdvisor
* */
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
List<Method> methods = new ArrayList<>();
/**
* adviceMethodFilter 逻辑:method 是 class中定义的 且 method 没有 @Pointcut 注解 就返回true
*
* 说白了就是将 类里面除了@Pointcut 标注的方法添加到 methods 集合中(会递归处理类的父类和接口里面的method)
* */
ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter);
if (methods.size() > 1) {
/**
* 升序排序:先按照 method 上面的注解排序(Around、Before、After、AfterReturning、AfterThrowing),如果相同在按照 methodName 排序。
* 注:没有这些注解的方法,的排序是最大的,所以会在最后面
* */
methods.sort(adviceMethodComparator);
}
return methods;
}
/**
* method 是 class中定义的 且 method 没有 @Pointcut 注解 就返回true
*/
// Exclude @Pointcut methods
private static final MethodFilter adviceMethodFilter = ReflectionUtils.USER_DECLARED_METHODS.and(method -> (
AnnotationUtils.getAnnotation(method, Pointcut.class) == null));
@Override
@Nullable
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) {
// 校验一下,简单来说就是类得有 @Aspect 注解
validate(aspectInstanceFactory.getAspectMetadata()
.getAspectClass());
/**
* 有 {@link AbstractAspectJAdvisorFactory#ASPECTJ_ANNOTATION_CLASSES} 注解才不会返回 null
* */
AspectJExpressionPointcut expressionPointcut = getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata()
.getAspectClass());
if (expressionPointcut == null) {
return null;
}
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
/**
* 就是拿到这些注解 {@link AbstractAspectJAdvisorFactory#ASPECTJ_ANNOTATION_CLASSES} 对应的属性值
* 装饰成 AspectJExpressionPointcut 对象返回
* <p>
* 没有 {@link AbstractAspectJAdvisorFactory#ASPECTJ_ANNOTATION_CLASSES} 直接 就返回null
*
* @param candidateAdviceMethod
* @param candidateAspectClass
* @return
*/
@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
if (this.beanFactory != null) {
ajexp.setBeanFactory(this.beanFactory);
}
return ajexp;
}
@SuppressWarnings("unchecked")
@Nullable
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[]{Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
// 当前的切点表达式
this.declaredPointcut = declaredPointcut;
// 切面的class对象
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
// 切面方法的名称
this.methodName = aspectJAdviceMethod.getName();
// 切面方法的参数类型
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
// 切面方法对象
this.aspectJAdviceMethod = aspectJAdviceMethod;
// aspectj的通知工厂
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
// aspectj切面实例工厂
this.aspectInstanceFactory = aspectInstanceFactory;
// 切面的顺序
this.declarationOrder = declarationOrder;
// 切面的名称
this.aspectName = aspectName;
// 判断当前的切面对象是否需要延时加载
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
// Static part of the pointcut is a lazy type.
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
// If it's not a dynamic pointcut, it may be optimized out
// by the Spring AOP infrastructure after the first evaluation.
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
} else {
// @Aspect("") 的时候
// A singleton aspect.
this.pointcut = this.declaredPointcut;
this.lazy = false;
// 将切面中的通知构造为advice通知对象
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//获取我们的切面类的class对象
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
//获取切面方法上的注解
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
//解析出来的注解信息是否为null
if (aspectJAnnotation == null) {
return null;
}
//再次判断是否是切面对象
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
AbstractAspectJAdvice springAdvice;
//判断标注在方法上的注解类型
switch (aspectJAnnotation.getAnnotationType()) {
//是PointCut注解 那么就抛出异常 因为在外面传递进来的方法已经排除了Pointcut的方法
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
//环绕通知 构建AspectJAroundAdvice
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
//前置通知 构建AspectJMethodBeforeAdvice
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
//后置通知 AspectJAfterAdvice
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
//返回通知 AspectJAfterReturningAdvice
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
//异常通知 AspectJAfterThrowingAdvice
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
//设置我们构建出来的通知对象的相关属性比如DeclarationOrder,在代理调用的时候,责任链顺序上会用到
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
创建代理
实例化前后置
/**
* 在Bean创建的生命周期会回调该方法,如果返回值不是null,
* 会执行 {@link BeanPostProcessor#postProcessAfterInitialization(Object, String)}
* 然后直接返回bean,不会进行后续bean生命周期的执行
*
* 在创建Bean的流程中还没调用构造器来实例化Bean的时候进行调用(实例化前后)
* AOP解析切面以及事务解析事务注解都是在这里完成的
* @param beanClass 要实例化的 Bean 的类
* @param beanName Bean 的名称
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
............
/**
* {@link AbstractAutoProxyCreator#customTargetSourceCreators} 属性不为null,就遍历 {@link TargetSourceCreator}
* 执行 {@link TargetSourceCreator#getTargetSource(Class, String)} 创建 TargetSource,返回值是null就直接return。
*
* 在这里使用 TargetSourceCreator 来创建代理对象也可以实现@Lazy的效果,即延时bean的创建,
* 因为这里直接返回了 代理对象,而执行代理对象在执行方法时会执行 {@link TargetSource#getTarget()} 拿到被代理对象,一般在这个方法就是 getBean 从而可以实现延时bean的实例化
*
* 注:TargetSource 封装了被代理对象,然后aop是对TargetSource进行代理
* */
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
// 有beanName
if (StringUtils.hasLength(beanName)) {
// 记录在 targetSourcedBeans(被代理对象集合) 中
this.targetSourcedBeans.add(beanName);
}
/**
* {@link AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean(Class, String, TargetSource)}
* 1. 会将容器中所有的 Advisor 都进行实例化,缓存起来。
* 2. 按照 类匹配 或者 (类匹配+AspectJ表达式匹配)
* 3. 返回满足条件的 Advisor
* */
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
/**
* 创建代理对象
* */
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
// 返回创建好的代理对象,这里返回值不是null,所以会中断后续Bean的声明周期,也就是后面的填充bean、初始化等等操作都不会执行了
return proxy;
}
return null;
}
查找匹配的Advisor
AbstractAdvisorAutoProxyCreator:
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
/**
* 查找符合条件的 Advisor
* */
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
/**
* 查找所有符合条件的顾问来自动代理此类。
*
* @param beanClass the clazz to find advisors for
* @param beanName the name of the currently proxied bean
* @return the empty List, not {@code null},
* if there are no pointcuts or interceptors
* @see #findCandidateAdvisors
* @see #sortAdvisors
* @see #extendAdvisors
*/
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
/**
* AnnotationAwareAspectJAutoProxyCreator 对 findCandidateAdvisors 进行了重写
*
* 查找候选的Advisors(这里拿到的是容器中所有的)
* 1. 从BeanFactory中找到 Advisor 类型的bean
* 2. 从BeanFactory中找到标注了 @Aspect 注解的bean,将标注了 @Around、@Before、@After、@AfterReturning、@AfterThrowing 的方法解析成 InstantiationModelAwarePointcutAdvisorImpl
* */
List<Advisor> candidateAdvisors = findCandidateAdvisors();
/**
* 查询当前类可以应用的 advisor(这里是筛选可以应用的)
*
* 匹配规则:类匹配 + 切入点表达式匹配
* */
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
/**
* 扩展 Advisor
*
* AnnotationAwareAspectJAutoProxyCreator 的父类 AspectJAwareAdvisorAutoProxyCreator 对 extendAdvisors 进行了重写
* 会添加这个作用第0个Advisor {@link ExposeInvocationInterceptor#INSTANCE}
* */
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
/**
* 升序排序
*
* 默认的排序规则 {@link AnnotationAwareOrderComparator.sort(advisors);} ,可以通过 Ordered接口、@Order、@Priority 设置排序值,
* 对于 InstantiationModelAwarePointcutAdvisorImpl 实例拿到的排序值其实是其@Aspectbean的 值
*
* AnnotationAwareAspectJAutoProxyCreator 的父类 AspectJAwareAdvisorAutoProxyCreator 对 sortAdvisors 进行了重写
* 重写的排序规则:使用 {@link AnnotationAwareOrderComparator } 得到排序值,如果compare 返回值是0,在判断是同一个 {@link AbstractAspectJAdvisorFactory#ASPECTJ_ANNOTATION_CLASSES} 注解
* 那就进行二次排序。
*
* 注:二次排序的参数值都是默认值,我看源码也没有特意修改该值,所以可以通过 第一次排序 就能设置 advisor 的顺序
* */
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
// 通过 ThreadLocal 记录 正在代理的beanName
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
/**
* 就是遍历所有的 candidateAdvisors,能匹配 beanClass 就收集到集合,然后将集合返回
*
* 匹配规则:类匹配 + 切入点表达式匹配
* */
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
} finally {
// 移除 正在代理的beanName
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
AopUtils:
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
for (Advisor candidate : candidateAdvisors) {
/**
* 是 IntroductionAdvisor 类型的,
* 只需要判断类满足即可 `((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass)`
* */
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
/**
*
* 通过 {@link AbstractAspectJAdvisorFactory#ASPECTJ_ANNOTATION_CLASSES} 注解解析成的 Advisor 是这个类型 {@link InstantiationModelAwarePointcutAdvisorImpl}
* {@link InstantiationModelAwarePointcutAdvisorImpl#getPointcut()}
* 如果切面类是@Aspect("") 那么该属性的返回值是这个类型 {@link AspectJExpressionPointcut }
*
* canApply 就是拿 AspectJExpressionPointcut,先进行类匹配、在匹配当前 clazz 是否满足切入点表达式
* */
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
// 类匹配满足 就行
return ((IntroductionAdvisor) advisor).getClassFilter()
.matches(targetClass);
} else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
/**
* 类匹配满足 在判断 类里面的方法 是否满足 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");
// 类匹配校验
if (!pc.getClassFilter()
.matches(targetClass)) {
return false;
}
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// 如果我们无论如何都匹配任何方法,则无需迭代方法...
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
// 用来记录 被代理类 和 被代理的所有接口 的类型
Set<Class<?>> classes = new LinkedHashSet<>();
// 不是jdk代理
if (!Proxy.isProxyClass(targetClass)) {
/**
* 是cglib代理生成的类,返回其父类
* 不是,直接返回 targetClass
* */
classes.add(ClassUtils.getUserClass(targetClass));
}
// 添加所有的接口
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
for (Class<?> clazz : classes) {
// 拿到类的所有方法
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
/**
* AspectJ 表达式匹配,匹配就返回true
*
* 默认是这个类型的 {@link AspectJExpressionPointcut#matches(Method, Class, boolean)}
* */
if (introductionAwareMethodMatcher
!= null ? introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) : methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
// 所有的方法都不匹配 AspectJ 表达式就返回false
return false;
}
创建代理
/**
* 为给定的bean创建代理对象,主要是通过ProxyFactory来创建代理对象,会有两个策略 cglib代理或者jdk代理,<br/>
* Create an AOP proxy for the given bean.
*
* @param beanClass the class of the bean
* @param beanName the name of the bean
* @param specificInterceptors the set of interceptors that is
* specific to this bean (may be empty, but not null)
* @param targetSource the TargetSource for the proxy,
* already pre-configured to access the bean
* @return the AOP proxy for the bean
* @see #buildAdvisors
*/
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
//
/**
* 给beanName对应的BeanDefinition {@link AutoProxyUtils#ORIGINAL_TARGET_CLASS_ATTRIBUTE} 属性,为beanClass
* 就是记录源对象是啥
* */
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
/**
* 关注这两个属性:proxyTargetClass、exposeProxy
*
* @EnableAspectJAutoProxy() 可以设置这两个属性值
* AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
* AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
*
* 属性 proxyTargetClass 在这里有用 {@link DefaultAopProxyFactory#createAopProxy(AdvisedSupport)}
* 属性 exposeProxy 在这里有用 {@link CglibAopProxy#getCallbacks(Class)}
* */
proxyFactory.copyFrom(this);
if (proxyFactory.isProxyTargetClass()) {
/**
* 显式处理 JDK 代理目标(用于引入通知场景)
*
* beanClass 是jdk代理产生的类
* */
// Explicit handling of JDK proxy targets (for introduction advice scenarios)
if (Proxy.isProxyClass(beanClass)) {
// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
for (Class<?> ifc : beanClass.getInterfaces()) {
// 记录实现的接口
proxyFactory.addInterface(ifc);
}
}
} else {
/**
* 就是检查BeanDefinition是否设置了属性
*
* @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
* @Compoent
* class A{}
*
* 这样子,shouldProxyTargetClass 就是 true
* */
//
// No proxyTargetClass flag enforced, let's apply our default checks...
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
/**
* 记录 beanClass 实现的自定义接口
* */
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
/**
* 主要是将 {@link AbstractAutoProxyCreator#interceptorNames} 的bean,作为通用的 Advisor。
* 通用的 Advisor 的优先级比specificInterceptors 要先执行
*
* 子类可以回调 {@link AbstractAutoProxyCreator#setInterceptorNames(String...)} 进行设置
* */
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
//
/**
* 设置 advisor
* 这里非常的关键,这里就是 IntroductionAdvisor 能实现不修改被代理的情况下还能进行类型转换的原因
* 添加的 advisor 是 IntroductionAdvisor 类型
* {@link AdvisedSupport#validateIntroductionAdvisor(IntroductionAdvisor)}
* {@link AdvisedSupport#validateIntroductionAdvisor(IntroductionAdvisor)}
* 就是会拿到Advisor的接口信息{@link IntroductionInfo#getInterfaces()}设置到proxyFactory中
* 注意,这里是会校验 是否是接口的,防止你乱搞 {@link AdvisedSupport#addInterface(Class)}
*
* 实例代码 {@link cn.haitaoss.javaconfig.aop.AopTest3.AspectDemo3}
* ((AopTest3.MyIntroduction)(context.getBean(AopTest3.AopDemo.class))).test1();
* */
proxyFactory.addAdvisors(advisors);
// 被代理对象。我们的普通bean 被装饰成 TargetSource 了
proxyFactory.setTargetSource(targetSource);
// 预留模板方法。空方法
customizeProxyFactory(proxyFactory);
/**
* 是否冻结代理,就是是否支持修改 advisors
* 看这些地方,都会校验这个属性
* 新增 {@link AdvisedSupport#addAdvisors(Collection)}
* 删除 {@link AdvisedSupport#removeAdvisor(int)}
* */
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
/**
* 创建代理对象
* {@link ProxyFactory#getProxy(ClassLoader)}
* {@link ProxyCreatorSupport#createAopProxy()}
*
*
* 创建 AopProxy {@link DefaultAopProxyFactory#createAopProxy(AdvisedSupport)}
* - 简单来说,被代理对象 不是接口 且 不是Proxy的子类
* 且 {@link AdvisedSupport#getProxiedInterfaces()}至多只有一个SpringProxy类型的接口
* 就创建 `new ObjenesisCglibAopProxy(config);`
* - 否则创建 `new JdkDynamicAopProxy(config);`
* 注:config 参数其实就是 ProxyFactory对象
*
* 使用 AopProxy 创建代理对象 {@link AopProxy#getProxy(ClassLoader)}
* {@link ObjenesisCglibAopProxy#getProxy(ClassLoader)}
* {@link JdkDynamicAopProxy#getProxy(ClassLoader)}
*
* ObjenesisCglibAopProxy 增强逻辑实现原理 {@link ObjenesisCglibAopProxy#getProxy(ClassLoader)}
* Enhancer enhancer = new Enhancer();
* enhancer.setCallbacks({@link CglibAopProxy#getCallbacks(Class)}); // 执行方法会回调callback
* 注:会设置 `new DynamicAdvisedInterceptor(this.advised);` callback,
* this 就是 ObjenesisCglibAopProxy,而其{@link CglibAopProxy#advised}属性
* 其实就是 ProxyFactory 从而可以拿到Advisors
* enhancer.setCallbackFilter(ProxyCallbackFilter);
* 返回要执行的 callback 的索引。在Cglib生成代理对象的字节码时会调CallbackFilter,来设置好每个方法的Callback是啥
* 设置这个属性,生成cglib生成的代理对象字节码,一看就知道了。
* `System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "C:\\Users\\RDS\\Desktop\\1");`
*
* 执行代理对象的方式时会执行 {@link CglibAopProxy.ProxyCallbackFilter#accept(Method)}
* 就是 除了 finalize、equals、hashcode 等,都会执行 DynamicAdvisedInterceptor 这个callback
* 也就是执行 {@link CglibAopProxy.DynamicAdvisedInterceptor#intercept(Object, Method, Object[], MethodProxy)}
* 1. exposeProxy 属性是 true,往 ThreadLocal中记录当前代理对象 `oldProxy=AopContext.setCurrentProxy(proxy)`
* 2. 获取被代理对象 {@link TargetSource#getTarget()}。这里也是很细节,
* 比如:
* - TargetSource实例是这个类型的 {@link AbstractBeanFactoryBasedTargetSource},所以每次获取target都是从IOC容器中拿,也就是说 如果bean是多例的,每次执行都会创建出新的对象。(@Lazy就是这么实现的)
* * - 而 Spring Aop,使用的是SingletonTargetSource,特点是将容器的对象缓存了,执行 `getTarget` 才能拿到被代理对象
* *
* 3. 根据method得到对应的拦截器链 {@link AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice(Method, Class)}
* 拦截器链是空:反射执行
* 拦截器链不是空:将拦截器链装饰成 CglibMethodInvocation ,然后执行{@link CglibAopProxy.CglibMethodInvocation#proceed()},其实就是执行其父类 {@link ReflectiveMethodInvocation#proceed()}
* 注:拦截器链就是 method 匹配到的 advisor 解析的结果,可以看这里 {@link DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice(Advised, Method, Class)}
* 4. exposeProxy 属性是 true,恢复之前的值 `AopContext.setCurrentProxy(oldProxy);`
*
* JdkDynamicAopProxy 增强逻辑的实现 {@link JdkDynamicAopProxy#getProxy(ClassLoader)}
* `Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);` 可以知道 第三个参数(InvocationHandler) 是 this,
* 也就是 JdkDynamicAopProxy,而其{@link JdkDynamicAopProxy#advised}属性 其实就是 ProxyFactory从而可以拿到Advisors
* 所以执行代理对象的方式时会执行 {@link JdkDynamicAopProxy#invoke(Object, Method, Object[])}
* 1. 是 equals(子类没有重写的情况下)、hashCode(子类没有重写的情况下)、DecoratingProxy.class 的方法、Advised.class 的方法
* 直接反射执行
* 2. exposeProxy 属性是 true,往 ThreadLocal中记录当前代理对象 `oldProxy=AopContext.setCurrentProxy(proxy)`
* 3. 根据method得到对应的拦截器链 {@link AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice(Method, Class)}
* 拦截器链是空:反射执行
* 拦截器链不是空:将拦截器链装饰成 ReflectiveMethodInvocation ,然后执行{@link ReflectiveMethodInvocation#proceed()}
* 注:拦截器链就是 method 匹配到的 advisor 解析的结果,可以看这里 {@link DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice(Advised, Method, Class)}
* 4. exposeProxy 属性是 true,恢复之前的值 `AopContext.setCurrentProxy(oldProxy);`
* */
return proxyFactory.getProxy(classLoader);
}
ProxyFactory:
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
DefaultProxyFacoory:
/**
* 简单来说,被代理对象 不是接口 且 不是Proxy的子类 且 {@link AdvisedSupport#getProxiedInterfaces()}至多只有一个SpringProxy类型的接口 就返回 ObjenesisCglibAopProxy
* 简单来说,代理对象是接口 或者 代理对象是JDK代理是生成的对象,才会使用JdkDynamicAopProxy
* @param config the AOP configuration in the form of an
* AdvisedSupport object
* @return
* @throws AopConfigException
*/
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 是优化 或者 是proxyTargetClass 或者 接口数量为0 或者 只有一个接口且接口实现了SpringProxy
if (!NativeDetector.inNativeImage() && (config.isOptimize() || config.isProxyTargetClass()
|| hasNoUserSuppliedProxyInterfaces(config))) {
// 拿到bean的类型(就是TargetSource装饰的类)
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: "
+ "Either an interface or a target is required for proxy creation.");
}
// 被代理对象是接口 或者 是Proxy的子类
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
// jdk代理
return new JdkDynamicAopProxy(config);
}
// cglib 代理
return new ObjenesisCglibAopProxy(config);
} else {
return new JdkDynamicAopProxy(config);
}
}
jdk动态代理
JdkDynamicAopProxy:
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
cglib动态代理
CglibAopProxy:
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
/**
* {@link AbstractBeanFactoryBasedTargetSource#getTargetClass()}
* 通过 targetBeanName 从 BeanFactory中得到类型
* */
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
// 被代理类 是cglib生成的类
if (rootClass.getName()
.contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
// 拿到真正的被代理类的类型
proxySuperClass = rootClass.getSuperclass();
// 拿到接口列表
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
// 将接口类型记录起来
this.advised.addInterface(additionalInterface);
}
}
// 啥都没干,打印日志而已
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader
&& ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
// 如果接口里面没有 SpringProxy、Advised、DecoratingProxy 的子类,就添加
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
// 很关键,设置 增强方法的逻辑
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
/**
* 如果设置了 CallbackFilter,就会根据 {@link CallbackFilter#accept(Method)} 返回的索引值
* 确定使用 那个 callback
* */
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// 生成代理对象
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
} catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass()
+ ": Common causes of this problem include using a final class or a non-visible class", ex);
} catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
初始化前后置
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
如果需要就创建代理
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
/**
* 在 {@link AbstractAutoProxyCreator#postProcessBeforeInstantiation} 的时候就创建了代理对象,
* 那就别搞了 直接返回入参bean
* */
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 表示 adviseBean 已经创建了代理对象 或者是 infrastructureBean
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 是 Advice、Pointcut、Advisor、AopInfrastructureBean 类型的子类
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
/**
* 就是拿到和这个bean 匹配的 advisors 集合 信息。会触发 Advisor类型的实例化、@Aspect bean的实例化
* {@link AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean(Class, String, TargetSource)}
* */
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
/**
* 哈哈哈哈。记录一下这个 bean 满足aop规则,创建了代理对象
* */
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
// 记录 虽然不是 advisor 但是也没有匹配 aop 规则的bean
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
获取早期bean引用
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.put(cacheKey, bean);
return wrapIfNecessary(bean, beanName, cacheKey);
}
执行代理
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
// 被代理的对象
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
// 执行的是equals方法不需要代理
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
// 执行的hashCode方法不需要代理
} else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
// DecoratingProxy不需要代理
} else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
} else if (!this.advised.opaque && method.getDeclaringClass()
.isInterface() && method.getDeclaringClass()
.isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
/**
* 这个配置是暴露我们的代理对象到线程变量中,需要搭配@EnableAspectJAutoProxy(exposeProxy = true)一起使用
* 比如在目标对象方法中再次获取代理对象可以使用这个AopContext.currentProxy()
* 还有的就是事务方法调用事务方法的时候也是用到这个
*/
if (this.advised.exposeProxy) {
// 把我们的代理对象暴露在线程变量中
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
// 获取被代理的目标对象
target = targetSource.getTarget();
// 被代理目标对象的class
Class<?> targetClass = (target != null ? target.getClass() : null);
// 根据 advisors 找到方法匹配的advisor,然后解析成 拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
// 如果拦截器链为空 反射执行
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} else {
// 装饰自 拦截器链
// We need to create a method invocation...
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
// 调用执行
retVal = invocation.proceed();
}
// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy)
&& !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
} else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
} finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
解析拦截器链
AdvisedSupport:
/**
* 将 advisors 中 method 匹配的 advisor,解析成 InterceptorAndDynamicMethodMatcher、MethodInterceptor 类型的集合 <br/>
*
* 默认使用这个工厂方法来生成 {@link AdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice(Advised, Method, Class)}
* 而这个工厂会使用 {@link DefaultAdvisorAdapterRegistry#getInterceptors(Advisor)} 来解析 advisor <br/>
* 最终会将 解析的结果,缓存起来 {@link AdvisedSupport#advisorChainFactory} <br/>
*/
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
// 将 advisors 中 method 匹配的 advisor,解析成 InterceptorAndDynamicMethodMatcher、MethodInterceptor 类型的集合
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
DefaultAdvisorChainFactory:
/**
* 将 advisors 中找出 method 匹配的 advisor,解析成 InterceptorAndDynamicMethodMatcher、MethodInterceptor 类型的集合
*
* @param config the AOP configuration in the form of an Advised object
* @param method the proxied method
* @param targetClass the target class (may be {@code null} to indicate a proxy without
* target object, in which case the method's declaring class is the next best option)
* @return
*/
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
for (Advisor advisor : advisors) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut()
.getClassFilter()
.matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut()
.getMethodMatcher();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
// 类匹配
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
// AspectJ 匹配
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
} else {
// AspectJ 匹配
match = mm.matches(method, actualClass);
}
if (match) {
// 将 advisor 通过适配器解析成 MethodInterceptor
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
/**
* 是运行时。说白了就是需要在执行的时候进行匹配,所以要把 MethodMatcher 传入
* 比如@Around、@Before、@After、@AfterThrowing、@AfterReturning生成的Advisor {@link AspectJExpressionPointcut#isRuntime()}
* */
if (mm.isRuntime()) {
/**
* 装饰成 InterceptorAndDynamicMethodMatcher
* 这个类型的特点是,拦截器执行时会执行 {@link MethodMatcher#matches(Method, Class)},是true在执行 {@link MethodInterceptor#invoke(MethodInvocation)}
*
* 执行的代码 {@link ReflectiveMethodInvocation#proceed()}
* */
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
} else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
} else if (advisor instanceof IntroductionAdvisor) {
// 类匹配
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter()
.matches(actualClass)) {
// 将 advisor 通过适配器解析成 MethodInterceptor
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
} else {
// 将 advisor 通过适配器解析成 MethodInterceptor
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
DefaultAdvisorAdapterRegistry:
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
// 是这个类型就直接添加
interceptors.add((MethodInterceptor) advice);
}
/**
* 使用适配器将 advice 解析成 MethodInterceptor
* 默认 MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter 有这三个适配器
* */
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[0]);
}
执行拦截器链
public Object proceed() throws Throwable {
// 从-1开始,下标=拦截器的长度-1的条件满足 表示执行到了最后一个拦截器的时候,此时执行目标方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 这个 ++ 很关键,因为 proceed() 是递归执行的,通过索引自增 实现了拦截器链的顺序执行
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
} else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
} else {
// 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);
}
}
① ExposeInvocationInterceptor.invoke方法:
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = invocation.get();
invocation.set(mi);
try {
return mi.proceed();
}
finally {
invocation.set(oldInvocation);
}
}
② AspectJAfterThrowingAdvice.invoke方法:
public Object invoke(MethodInvocation mi) throws Throwable {
try {
//执行下一个通知/拦截器
return mi.proceed();
}
catch (Throwable ex) {
//抛出异常
if (shouldInvokeOnThrowing(ex)) {
//执行异常通知
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}
③ AfterReturningAdviceInterceptor.invoke方法:
public Object invoke(MethodInvocation mi) throws Throwable {
//执行下一个通知/拦截器
Object retVal = mi.proceed();
//返回通知方法
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
④ AspectJAfterAdvice.invoke方法:
public Object invoke(MethodInvocation mi) throws Throwable {
try {
//执行下一个通知/拦截器
return mi.proceed();
}
finally {
//后置通知的方法总是会被执行 原因就在这finally
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
⑤ AspectJAroundAdvice.invoke方法:
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
JoinPointMatch jpm = getJoinPointMatch(pmi);
return invokeAdviceMethod(pjp, jpm, null, null);
}
⑥ MethodBeforeAdviceInterceptor.invoke方法:
public Object invoke(MethodInvocation mi) throws Throwable {
//执行前置通知的方法
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
//执行下一个通知/拦截器,但是该拦截器是最后一个了,所以会调用目标方法
return mi.proceed();
}