死磕Spring系列:SpringAOP源码解析

1. 术语

在SpringAOP中,有很多专业术语,已经了解的小伙伴可以略过,不了解的朋友就需要注意看一下啦,不然会很懵的哟。

  • Aspect(切面)

    跨多个类的关注点的模块化,与垂直调用的业务树不同,以横切的方式存在。

  • Join point(连接点)

    程序执行过程的一个点,总是代表一个方法执行。

  • Advice (通知)

    在特定连接点采取的行动,有Around、Before、After类型的Advice。

  • Pointcut(切入点)

    匹配连接点的断言,Advice与切入点表达式相关联,并在切入点匹配的任何连接点处运行。切入点表达式匹配的连接点的概念是AOP的核心,Spring默认使用AspectJ切入点表达式语言。

  • Advisor(顾问)

    Advisor是Advice的包装,其中PointcutAdvisor是Advice与Pointcut的包装,DefaultIntroductionAdvisor是Advice与IntroductionInfo的包装。

  • Introduction(引入)

    可以将其他接口和实现动态引入到targetClass中。

  • Target object(目标对象)

    将要被增强的对象。

  • AOP proxy(AOP代理)

    由AOP框架为了实现切面功能而创建的对象,在Spring框架中,一个AOP代理是JDK动态代理或者CGLIB代理。

  • Weaving(织入)

    将通知(Advice)切入连接点(Join point)的过程叫织入。

2 启用AOP

要使用SpringAOP,在SpringBoot项目中,需要在启动类使用一个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向当前IOC容器中引入了一个AspectJAutoProxyRegistrar类。

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.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

      AnnotationAttributes enableAspectJAutoProxy =
            AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
      if (enableAspectJAutoProxy != null) {
         if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
         }
         if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
            AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
         }
      }
   }

}

这个类实现了ImportBeanDefinitionRegistrar接口,所以在项目启动并执行BeanDefinitionRegistryPostProcessor的时候,可以调用registerBeanDefinitions方法来向IOC中注入BeanDefinition。

这里首先向IOC注册一个用于代理创建的类,再将注解中的属性设置到这个类的属性值中。

2.1 注册代理创建类

AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
	return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {

	return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

通过逐层调用,最终到了这个方法里面:

@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
      Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {

   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

   if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
      BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
      if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
         int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
         int requiredPriority = findPriorityForClass(cls);
         if (currentPriority < requiredPriority) {
            apcDefinition.setBeanClassName(cls.getName());
         }
      }
      return null;
   }

   RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
   beanDefinition.setSource(source);
   beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
   beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
   registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
   return beanDefinition;
}

这个方法的主要作用就是向IOC容器注册一个名称为org.springframework.aop.config.internalAutoProxyCreator的beanDefinition。

逻辑中会先判断当前IOC中是否含有一个名称为org.springframework.aop.config.internalAutoProxyCreator的beanDefinition。

如果有,就根据优先级来对这个BeanDefinition的class进行修改,这里的直接影响就是后面实例化后,beanName为org.springframework.aop.config.internalAutoProxyCreator的bean的class类型会改变。而这里的优先级是根据一个List判断的,

APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);

类在这个list中的位置越靠后,越优先使用。

如果没有,那就新建一个并注册到IOC中。

3. 代理创建类的处理

首先来看一下AnnotationAwareAspectJAutoProxyCreator的类图:

image-20220421101615045

可以看到,AnnotationAwareAspectJAutoProxyCreator的继承关系为:

AnnotationAwareAspectJAutoProxyCreator -> SmartInstantiationAwareBeanPostProcessor -> InstantiationAwareBeanPostProcessor -> BeanPostProcessor

所以注意的是,在bean的获取期间,可能会调用到的后置处理方法:

  • SmartInstantiationAwareBeanPostProcessor
    • getEarlyBeanReference
  • InstantiationAwareBeanPostProcessor
    • postProcessBeforeInstantiation
    • postProcessAfterInstantiation
  • BeanPostProcessor
    • postProcessBeforeInitialization
    • postProcessAfterInitialization

在这些后置处理方法中,AnnotationAwareAspectJAutoProxyCreator重写了getEarlyBeanReferencepostProcessBeforeInstantiationpostProcessAfterInitialization这三个方法的逻辑,所以接下来我们将对这些方法来进行解析。

SmartInstantiationAwareBeanPostProcessor是在从三级缓存中取对象时调用的,但是又并非每个bean的创建都要通过三级缓存的ObjectFactory的getObject去获取。

所以我们先对InstantiationAwareBeanPostProcessor来进行说明。

3.1 InstantiationAwareBeanPostProcessor

AbstractAutoProxyCreatorInstantiationAwareBeanPostProcessor类中的 postProcessBeforeInstantiationpostProcessAfterInitialization方法进行了重写,我们来具体看下:

3.1.1 初始化前处理

@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    // 生成beanName的缓存key
   Object cacheKey = getCacheKey(beanClass, beanName);
	// beanName无值或者targetSourcedBeans不包含此bean
   if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
      	// 如果advisedBeans已经包含此值,则return
       if (this.advisedBeans.containsKey(cacheKey)) {
         return null;
      }
       // 如果是一个基础类(Advice/Pointcut...)或者是一个“original instance”
      if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
          // 放入advisedBeans并设置值为false
         this.advisedBeans.put(cacheKey, Boolean.FALSE);
         return null;
      }
   }

   // 找到自定义的TargetSource
   TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
    // targetSource不为空才走代理逻辑
   if (targetSource != null) {
      if (StringUtils.hasLength(beanName)) {
          // 添加到targetSourcedBeans集合
         this.targetSourcedBeans.add(beanName);
      }
       // 获取所有Advisor
      Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
       // 创建一个jdk/cglib代理对象
      Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
       // 保存代理后的类class
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   }

   return null;
}

细节解读

来对代码段进行解读,

Object cacheKey = getCacheKey(beanClass, beanName);

如果这个类是一个FactoryBean,那就用这个将&+beanName作为cacheKey,否则直接用beanName。

if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
   if (this.advisedBeans.containsKey(cacheKey)) {
      return null;
   }
   if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
      this.advisedBeans.put(cacheKey, Boolean.FALSE);
      return null;
   }
}

在beanName不为空,且不在targetSourcedBeans中的情况下,

  • 如果advisedBeans包含了此cacheKey,就return null。

  • 如果是infrastructureClass或者shouldSkip,那么将cacheKey作为key,Boolean.FALSE放入advisedBeans这个Map中,且return null。

怎样判断是否是infrastructureClass?

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

如果一个类是AdvicePointcutAdvisorAopInfrastructureBean的子类,那它就是一个infrastructureClass

怎样判断是否shouldSkip?

static boolean isOriginalInstance(String beanName, Class<?> beanClass) {
   if (!StringUtils.hasLength(beanName) || beanName.length() !=
         beanClass.getName().length() + AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX.length()) {
      return false;
   }
   return (beanName.startsWith(beanClass.getName()) &&
         beanName.endsWith(AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX));
}

如果beanName为空或者beanName的长度不等于beanClass的name加上ORIGINAL_INSTANCE_SUFFIX后缀的长度,那就不是originalInstance

如果beanName以beanClass的name开头,且以ORIGINAL_INSTANCE_SUFFIX结尾的就是originalInstance。

这里我就有点疑惑,为什么不用equals直接去判断两者的值是否等,而是用长度判断后再用startsWith+endsWith去判断呢?

最后,如果是originalInstance,那就应该跳过。

TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
   if (StringUtils.hasLength(beanName)) {
      this.targetSourcedBeans.add(beanName);
   }
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
   Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
   this.proxyTypes.put(cacheKey, proxy.getClass());
   return proxy;
}

主要逻辑:

  • 获取自定义的TargetSource。
  • 将使用了TargetSource的beanName放入targetSourcedBeans。
  • 获取并组装bean的Advice和Advisor信息。
  • 创建代理对象
  • 将cacheKey(基于beanName)和代理类的类信息保存到proxyTypes。

其中,getCustomTargetSource:

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.isTraceEnabled()) {
               logger.trace("TargetSourceCreator [" + tsc +
                     "] found custom TargetSource for bean with name '" + beanName + "'");
            }
            return ts;
         }
      }
   }

   // No custom TargetSource found.
   return null;
}

可以看到,是从customTargetSourceCreators变量中取出所有的TargetSourceCreator,接着调用其getTargetSource方法得到一个TargetSource。如果说我们需要实现我们自己的TargetSource,那就需要自己创建一个TargetSourceCreator,然后放入到customTargetSourceCreators中。

其中,getAdvicesAndAdvisorsForBean

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

这里就是找到所有符合条件的Advisor,如果为空,返回null,否则返回所有符合的Advisor。

findEligibleAdvisors:

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    // 查找所有候选的Advisor
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
    // 筛选出能被应用的Advisor
   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    // 扩展操作
   extendAdvisors(eligibleAdvisors);
   if (!eligibleAdvisors.isEmpty()) {
       // 排序
      eligibleAdvisors = sortAdvisors(eligibleAdvisors);
   }
   return eligibleAdvisors;
}

findCandidateAdvisors

AnnotationAwareAspectJAutoProxyCreator中重写了此方法:

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.
   if (this.aspectJAdvisorsBuilder != null) {
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   }
   return advisors;
}

这里首先是调用了父类的findCandidateAdvisors方法得到所有Advisor,其次再aspectJAdvisorsBuilder.buildAspectJAdvisors()来添加Advisor。

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findCandidateAdvisors:

protected List<Advisor> findCandidateAdvisors() {
   Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
   return this.advisorRetrievalHelper.findAdvisorBeans();
}

org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans:

public List<Advisor> findAdvisorBeans() {
   // advisorNames缓存
   String[] advisorNames = this.cachedAdvisorBeanNames;
   if (advisorNames == null) {
      // 在beanFactory中寻找Advisor
      advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
            this.beanFactory, Advisor.class, true, false);
      this.cachedAdvisorBeanNames = advisorNames;
   }
   if (advisorNames.length == 0) {
      return new ArrayList<>();
   }

   List<Advisor> advisors = new ArrayList<>();
   for (String name : advisorNames) {
      if (isEligibleBean(name)) {
         if (this.beanFactory.isCurrentlyInCreation(name)) {
            if (logger.isTraceEnabled()) {
               logger.trace("Skipping currently created advisor '" + name + "'");
            }
         }
         else {
            try {
                // 添加Advisor bean到advisors中
               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;
}

上述主要逻辑就是从beanFactory中获取Advisor bean。

继续分析this.aspectJAdvisorsBuilder.buildAspectJAdvisors()

public List<Advisor> buildAspectJAdvisors() {
   List<String> aspectNames = this.aspectBeanNames;

   if (aspectNames == null) {
      synchronized (this) {
         aspectNames = this.aspectBeanNames;
         if (aspectNames == null) {
            List<Advisor> advisors = new ArrayList<>();
            aspectNames = new ArrayList<>();
             // 获取beanFactory中所有的beanName
            String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                  this.beanFactory, Object.class, true, false);
            for (String beanName : beanNames) {
                // 判断是否应该跳过
               if (!isEligibleBean(beanName)) {
                  continue;
               }
               // 获取bean的Class
               Class<?> beanType = this.beanFactory.getType(beanName, false);
               if (beanType == null) {
                  continue;
               }
                // 如果这个bean被@Aspect所注解
               if (this.advisorFactory.isAspect(beanType)) {
                   // 加入aspectNames集合
                  aspectNames.add(beanName);
                   // 生成AspectMetadata
                  AspectMetadata amd = new AspectMetadata(beanType, beanName);
                  // 默认为SINGLETON
                   if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                     MetadataAwareAspectInstanceFactory factory =
                           new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                       // 查找Around/Before/After/AfterReturning/AfterThrowing注解的method,包装为Advisor
                       // 内部将Advice细分为BeforeAdvice、AfterAdvice等等
                     List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                       // 如果是singleton
                     if (this.beanFactory.isSingleton(beanName)) {
                         // 将所有Advisor放入缓存
                        this.advisorsCache.put(beanName, classAdvisors);
                     }
                     else {
                         // 非singleton则将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");
                     }
                     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<>();
    // 到这里说明aspectNames有值,后续就走缓存逻辑
   for (String aspectName : aspectNames) {
      List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
      if (cachedAdvisors != null) {
          // 缓存中有值,说明是singleton,添加到advisors中
         advisors.addAll(cachedAdvisors);
      }
      else {
          // 非singleton,获取缓存中的factory,使用factory获取所有Advisor
         MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
          // 添加到advisors中
         advisors.addAll(this.advisorFactory.getAdvisors(factory));
      }
   }
   return advisors;
}

回到主流程,其中createProxy

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

   if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
       // 向其BeanDefinition中设置originalTargetClass属性
      AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
   }

   ProxyFactory proxyFactory = new ProxyFactory();
    // 复制当前类中的proxyTargetClass、optimize、exposeProxy、frozen、opaque属性值
   proxyFactory.copyFrom(this);
	// proxyTargetClass值为true
   if (proxyFactory.isProxyTargetClass()) {
      // beanClass是Proxy的子类
      if (Proxy.isProxyClass(beanClass)) {
         for (Class<?> ifc : beanClass.getInterfaces()) {
             // 向proxyFactory中添加beanClass的接口
            proxyFactory.addInterface(ifc);
         }
      }
   }
   else {
       // 如果BeanDefinition中preserveTargetClass属性为true
      if (shouldProxyTargetClass(beanClass, beanName)) {
          // 设置proxyTargetClass为true
         proxyFactory.setProxyTargetClass(true);
      }
      else {
          // 计算处理,接下来单独解析
         evaluateProxyInterfaces(beanClass, proxyFactory);
      }
   }
	// 构建所有Advisor
   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
   proxyFactory.addAdvisors(advisors);
   proxyFactory.setTargetSource(targetSource);
    // 自定义操作proxyFactory
   customizeProxyFactory(proxyFactory);

   proxyFactory.setFrozen(this.freezeProxy);
   if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
   }

   ClassLoader classLoader = getProxyClassLoader();
   if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
      classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
   }
    // 通过proxyFactory获取代理对象
   return proxyFactory.getProxy(classLoader);
}

对于evaluateProxyInterfaces方法:

protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
   Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
   boolean hasReasonableProxyInterface = false;
   for (Class<?> ifc : targetInterfaces) {
       // 不是配置类的回调接口且不是内部的语言接口且有定义方法
      if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
            ifc.getMethods().length > 0) {
         hasReasonableProxyInterface = true;
         break;
      }
   }
   if (hasReasonableProxyInterface) {
      // 向proxyFactory中添加interface
      for (Class<?> ifc : targetInterfaces) {
         proxyFactory.addInterface(ifc);
      }
   }
   else {
       // 设置proxyTargetClass为true
      proxyFactory.setProxyTargetClass(true);
   }

判断是否是配置类的回调接口isConfigurationCallbackInterface:

protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
    // 如果ifc是InitializingBean或者DisposableBean或者Closeable或者AutoCloseable或者是Aware的是实现类,那就是一个ConfigurationCallbackInterface
   return (InitializingBean.class == ifc || DisposableBean.class == ifc || Closeable.class == ifc ||
         AutoCloseable.class == ifc || ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
}

判断是否是内部的语言接口isInternalLanguageInterface

protected boolean isInternalLanguageInterface(Class<?> ifc) {
	// name为"groovy.lang.GroovyObject"或者以".cglib.proxy.Factory"结尾或者以".bytebuddy.MockAccess"结尾
   return (ifc.getName().equals("groovy.lang.GroovyObject") ||
         ifc.getName().endsWith(".cglib.proxy.Factory") ||
         ifc.getName().endsWith(".bytebuddy.MockAccess"));
}

上面很大一部分都是为了设置proxyTargetClassinterface,为的就是后续创建一个proxy对象。

proxyFactory.getProxy(classLoader)中:

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

首先createAopProxy()使用来创建一个代理,里面实现了根据需要来创建JDK动态代理还是CGLIB代理,再通过getProxy来创建一个具体的代理对象。

createAopProxy中:

protected final synchronized AopProxy createAopProxy() {
   if (!this.active) {
      activate();
   }
   return getAopProxyFactory().createAopProxy(this);
}

public AopProxyFactory getAopProxyFactory() {
    // 默认为DefaultAopProxyFactory
	return this.aopProxyFactory;
}

DefaultAopProxyFactory#createAopProxy:

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
	// !NativeDetector.inNativeImage() 不是在image构建上下文且image运行时调用
    // config.isOptimize() 代理是否应该执行主动优化
    // config.isProxyTargetClass() 是否直接代理目标类以及任何接口
    // hasNoUserSuppliedProxyInterfaces(config) 没有接口或只有一个SpringProxy的接口
   if (!NativeDetector.inNativeImage() &&
         (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
      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的子类或者是一个lamda表达式
      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || AopProxyUtils.isLambda(targetClass)) {
          // 返回jdk代理
         return new JdkDynamicAopProxy(config);
      }
       // 返回cglib代理
      return new ObjenesisCglibAopProxy(config);
   }
   else {
       // 返回jdk代理
      return new JdkDynamicAopProxy(config);
   }
}

小结一下:如果不是在image构建上下文且image运行时调用且(代理是否应该执行主动优化或直接代理目标类以及任何接口或(没有接口或只有一个SpringProxy的接口))且目标类不是一个接口且不是Proxy的子类且不是一个lambda表达式,那么就使用CGLIB代理,其他情况使用JDK动态代理。

得到代理后,就是按情况调用其getProxy方法来生成代理对象。

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

这里就是使用Proxy.newProxyInstance来创建代理对象,classLoader是类加载器,this.proxiedInterfaces是目标类的接口,this是一个InvocationHandler,也就是说JdkDynamicAopProxy是一个InvocationHandler的实现类,实现了invoke方法。

ObjenesisCglibAopProxy

ObjenesisCglibAopProxy继承自CglibAopProxy,并没有重写CglibAopProxy中的getProxy方法。

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

   try {
       // 得到目标类的class
      Class<?> rootClass = this.advised.getTargetClass();
      Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

      Class<?> proxySuperClass = rootClass;
       // 如果目标类已经是一个代理类
      if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
          // 获取目标类的父类(其实就是最原始的目标类)
         proxySuperClass = rootClass.getSuperclass();
         Class<?>[] additionalInterfaces = rootClass.getInterfaces();
          // 向当前advice中添加当前目标类的接口
         for (Class<?> additionalInterface : additionalInterfaces) {
            this.advised.addInterface(additionalInterface);
         }
      }

      // 校验类中的method并根据log配置判断是否打印相关信息
      validateClassIfNecessary(proxySuperClass, classLoader);

      // 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);
       // 设置被代理的接口
      enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
       // 设置命名规则
      enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
       // 设置用于从生成器创建字节码的策略
      enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));

       // 获取所有回调类(如MethodInterceptor)
      Callback[] callbacks = getCallbacks(rootClass);
       // 获取所有回调类的class
      Class<?>[] types = new Class<?>[callbacks.length];
      for (int x = 0; x < types.length; x++) {
         types[x] = callbacks[x].getClass();
      }
      // 用来判断具体该执行哪个回调
      enhancer.setCallbackFilter(new ProxyCallbackFilter(
            this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
       // 设置回调类class
      enhancer.setCallbackTypes(types);

      // 生成代理类的class并创建一个代理类实例对象
      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);
   }
}

具体方法分析:

  • AopProxyUtils.completeProxiedInterfaces
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
    // 获取所有被代理的接口
   Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
    // 没有实现的接口
   if (specifiedInterfaces.length == 0) {
      // No user-specified interfaces: check whether target class is an interface.
      Class<?> targetClass = advised.getTargetClass();
      if (targetClass != null) {
          // 如果目标类是一个接口
         if (targetClass.isInterface()) {
            advised.setInterfaces(targetClass);
         }
          // 如果目标类是Proxy的子类或是一个lambda表达式
         else if (Proxy.isProxyClass(targetClass) || isLambda(targetClass)) {
            advised.setInterfaces(targetClass.getInterfaces());
         }
         specifiedInterfaces = advised.getProxiedInterfaces();
      }
   }
    // +3是因为能确定在这里最多需要添加3个元素,防止ArrayList自动扩容引发性能问题(空间换时间)
   List<Class<?>> proxiedInterfaces = new ArrayList<>(specifiedInterfaces.length + 3);
   for (Class<?> ifc : specifiedInterfaces) {
      // 适配jdk17中的密封接口
      if (isSealedMethod == null || Boolean.FALSE.equals(ReflectionUtils.invokeMethod(isSealedMethod, ifc))) {
         proxiedInterfaces.add(ifc);
      }
   }
    // isInterfaceProxied判断在advised的接口中是否有包含某个子类的接口
    // 如果目标类的接口中不包含可指定为SpringProxy的类(SpringProxy、SpringProxy子类、SpringProxy实现类)
   if (!advised.isInterfaceProxied(SpringProxy.class)) {
      proxiedInterfaces.add(SpringProxy.class);
   }
    // 不应该阻止由此配置创建的代理被强制转换为Advice,且目标类的接口中不包含可指定为Advised的类
   if (!advised.isOpaque() && !advised.isInterfaceProxied(Advised.class)) {
      proxiedInterfaces.add(Advised.class);
   }
    // 如果需要暴露DecoratingProxy,且目标类的接口中不包含可指定为DecoratingProxy的类
   if (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class)) {
      proxiedInterfaces.add(DecoratingProxy.class);
   }
   return ClassUtils.toClassArray(proxiedInterfaces);
}
  • getCallbacks
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
   // 调用时是否暴露代理对象,可通过AopContext这个ThreadLocal获取
   boolean exposeProxy = this.advised.isExposeProxy();
   // 配置是否被冻结
   boolean isFrozen = this.advised.isFrozen();
    // TargetSouce是否是static类型的
   boolean isStatic = this.advised.getTargetSource().isStatic();

   // aop带Adviced的拦截处理
   Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

   // 不带Adviced的拦截处理
   Callback targetInterceptor;
   // 暴露代理(运行时向AopContext这个ThreadLocal中暴露proxy对象)
   if (exposeProxy) {
      // 根据TargetSource的修饰符来判断使用哪个拦截器
      targetInterceptor = (isStatic ?
            new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
            new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
   }
   else {
      // 根据TargetSource的修饰符来判断使用哪个拦截器
      targetInterceptor = (isStatic ?
            new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
            new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
   }

   // dispatcher
   Callback targetDispatcher = (isStatic ?
         new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());

   // 主要的callback
   Callback[] mainCallbacks = new Callback[] {
         aopInterceptor,
         targetInterceptor,
         new SerializableNoOp(),
         targetDispatcher, this.advisedDispatcher,
         new EqualsInterceptor(this.advised),
         new HashCodeInterceptor(this.advised)
   };

   Callback[] callbacks;

   // 静态类&Advised被冻结
   if (isStatic && isFrozen) {
      Method[] methods = rootClass.getMethods();
      Callback[] fixedCallbacks = new Callback[methods.length];
      this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);

      // TODO: small memory optimization here (can skip creation for methods with no advice)
      for (int x = 0; x < methods.length; x++) {
         Method method = methods[x];
         // 获取method匹配上的所有Advice
         List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
         // 包装成FixedChainStaticTargetInterceptor
         fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
               chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
         // 将method与索引x的关系保存进fixedInterceptorMap
         this.fixedInterceptorMap.put(method, x);
      }

	  // 将mainCallbacks与fixedCallbacks都放入callbacks中
      callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
      System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
      System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
      // 作为间隔索引,可以得知callbacks哪些是mainCallbacks,哪些是fixedCallbacks
      this.fixedInterceptorOffset = mainCallbacks.length;
   }
   else {
      callbacks = mainCallbacks;
   }
   return callbacks;
}
  • ProxyCallbackFilter
new ProxyCallbackFilter(
      this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)

ProxyCallbackFilter是通过其accept方法来返回一个int值,这个值就作为下标去callbacks数组中找到对应的callback进行执行。

首先看下CglibAopProxy中定义的index:

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;

再看看固定的callback:

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。

@Override
public int accept(Method method) {
   if (AopUtils.isFinalizeMethod(method)) {
      logger.trace("Found finalize() method - using NO_OVERRIDE");
       // 是一个final方法,则不代理方法
      return NO_OVERRIDE;
   }
   // 不应该阻止由此配置创建的代理被强制转换为Advice且该方法所属类是一个接口且该类是Advised的父类
   if (!this.advised.isOpaque() && method.getDeclaringClass().isInterface() &&
         method.getDeclaringClass().isAssignableFrom(Advised.class)) {
      if (logger.isTraceEnabled()) {
         logger.trace("Method is declared on Advised interface: " + method);
      }
      // 应用dispatch callback
      return DISPATCH_ADVISED;
   }
   // 如果是一个equals方法
   if (AopUtils.isEqualsMethod(method)) {
      if (logger.isTraceEnabled()) {
         logger.trace("Found 'equals' method: " + method);
      }
      // 应用invoke callback
      return INVOKE_EQUALS;
   }
   // 如果是一个hashCode方法
   if (AopUtils.isHashCodeMethod(method)) {
      if (logger.isTraceEnabled()) {
         logger.trace("Found 'hashCode' method: " + method);
      }
      // 应用hashcode callback
      return INVOKE_HASHCODE;
   }
   Class<?> targetClass = this.advised.getTargetClass();
   // 获取该方法所有匹配的Advice
   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();
   // 如果有匹配的Advice且配置未冻结
   if (haveAdvice || !isFrozen) {
      // 如果暴露代理
      if (exposeProxy) {
         if (logger.isTraceEnabled()) {
            logger.trace("Must expose proxy on advised method: " + method);
         }
         // 应用aop callback
         return AOP_PROXY;
      }
      // 如果是TargetSource是static类型,且冻结了配置且fixedInterceptorMap含有对此method的interceptor
      if (isStatic && isFrozen && this.fixedInterceptorMap.containsKey(method)) {
         if (logger.isTraceEnabled()) {
            logger.trace("Method has advice and optimizations are enabled: " + method);
         }
         // 找到其interceptor的索引
         int index = this.fixedInterceptorMap.get(method);
         // 因为callbacks中是mainCallbacks + fixedCallbacks,而index是fixedCallbacks中的下标,fixedInterceptorOffset表示mainCallbacks的长度,所以在callbacks的下标即为index + this.fixedInterceptorOffset
         return (index + this.fixedInterceptorOffset);
      }
      else {
         if (logger.isTraceEnabled()) {
            logger.trace("Unable to apply any optimizations to advised method: " + method);
         }
         // 其他情况使用aop callback
         return AOP_PROXY;
      }
   }
   else {
      // See if the return type of the method is outside the class hierarchy of the target type.
      // If so we know it never needs to have return type massage and can use a dispatcher.
      // If the proxy is being exposed, then must use the interceptor the correct one is already
      // configured. If the target is not static, then we cannot use a dispatcher because the
      // target needs to be explicitly released after the invocation.
      // 暴露proxy或不是static类型
      if (exposeProxy || !isStatic) {
         // 应用target callback
         return INVOKE_TARGET;
      }
      Class<?> returnType = method.getReturnType();
      // 如果目标类可被声明为方法返回的类型
      if (targetClass != null && returnType.isAssignableFrom(targetClass)) {
         if (logger.isTraceEnabled()) {
            logger.trace("Method return type is assignable from target type and " +
                  "may therefore return 'this' - using INVOKE_TARGET: " + method);
         }
         // 应用target callback
         return INVOKE_TARGET;
      }
      else {
         if (logger.isTraceEnabled()) {
            logger.trace("Method return type ensures 'this' cannot be returned - " +
                  "using DISPATCH_TARGET: " + method);
         }
         // 应用dispatch target callback
         return DISPATCH_TARGET;
      }
   }
}

这里得说一下根据method来找到Advice得逻辑,这里至关重要。

  • AddvicedSupport.getInterceptorsAndDynamicInterceptionAdvice

3.1.2 初始化后处理

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
   if (bean != null) {
       // 生成缓存key
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
       // 如果这个bean不存在于earlyProxyReferences中
      if (this.earlyProxyReferences.remove(cacheKey) != bean) {
          // 有需要则执行代理逻辑
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

earlyProxyReferences对象,是保存早期代理引用对象的一个Map,如果这个bean被调用了从三级缓存中获取的方法,会调用SmartInstantiationAwareBeanPostProcessorgetEarlyBeanReference方法,AbstractAutoProxyCreator实现了其getEarlyBeanReference方法,在其中会将处理的bean放入earlyProxyReferences这个Map中,且执行代理逻辑。所以在这里对earlyProxyReferences对象的操作,其实就是为了避免重复执行wrapIfNecessary代理逻辑。

细节解读

wrapIfNecessary:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    // 如果这个bean是TargetSource,则不代理
   if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
      return bean;
   }
    // 如果已经存在于advisedBeans中,且值为false,则跳过代理
   if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
      return bean;
   }
    // 如果是一个基础类(Advice/Pointcut...)或者是一个“original instance”
   if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
       // 放入advisedBeans并设置值为false
      this.advisedBeans.put(cacheKey, Boolean.FALSE);
      return bean;
   }

   // 获取所有Advisor
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   if (specificInterceptors != DO_NOT_PROXY) {
       // 放入advisedBeans并设置值为true
      this.advisedBeans.put(cacheKey, Boolean.TRUE);
       // 创建一个jdk/cglib代理对象
      Object proxy = createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
      	// 保存代理后的类class
       this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   }
	// 放入advisedBeans并设置值为false
   this.advisedBeans.put(cacheKey, Boolean.FALSE);
   return bean;
}

知识点:

  • targetSourcedBeans这个Map是在InstantiationAwareBeanPostProcessor执行postProcessBeforeInstantiation方法的时候赋值的。

  • 经过后置处理器的调用之后,advisedBeans这个Map中保存的是所有非TargetSource bean的是否生成代理类的关系。

3.2 SmartInstantiationAwareBeanPostProcessor

这个方法不一定能调用到,因为只有从三级缓存中根据ObjectFactory获取对象时才能走此逻辑,比如一个bean正在创建中,而另外一个bean又来获取这个正在创建中的bean。

@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
    // 生成缓存key
   Object cacheKey = getCacheKey(bean.getClass(), beanName);
    // 放入早期引用Map
   this.earlyProxyReferences.put(cacheKey, bean);
    // 有需要则执行代理逻辑
   return wrapIfNecessary(bean, beanName, cacheKey);
}

wrapIfNecessary的解析上面我们已经解析过,不再赘述。

4 执行

代理类已经创建好了,接下来就是调用这个代理类的方法。

大家都知道,JDK动态代理需要一个InvocationHandler、CGLIB需要一个MethodIntercepter来定义代理方法的具体执行逻辑。在

上述的代理过程中,我们通过JdkDynamicAopProxy或ObjenesisCglibAopProxy去产生一个代理对象,所以具体执行逻辑会不同,我们来分别看看。

4.1 JdkDynamicAopProxy

JDK动态代理的执行逻辑就是要实现一个InvocationHandler接口的invoke方法,JdkDynamicAopProxy本质就是一个InvocationHandler的是实现类,所以来看看这个方法的主要逻辑:

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 {
      if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
         // 自己未实现equals方法,且调用的是equals方法
         return equals(args[0]);
      }
      else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
         // 自己未实现hashCode方法,且调用的是hashCode方法
         return hashCode();
      }
      else if (method.getDeclaringClass() == DecoratingProxy.class) {
         // 获取最终的target Class
         return AopProxyUtils.ultimateTargetClass(this.advised);
      }
      else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
            method.getDeclaringClass().isAssignableFrom(Advised.class)) {
         // 此method是一个继承自Advised的接口申明的方法
         // 以反射执行
         return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
      }

      Object retVal;

      if (this.advised.exposeProxy) {
         // 向ThreadLocal暴露
         oldProxy = AopContext.setCurrentProxy(proxy);
         setProxyContext = true;
      }

      // 获取目标类
      target = targetSource.getTarget();
      Class<?> targetClass = (target != null ? target.getClass() : null);

      // 获取匹配到该方法的所有inceptor
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

      // 如果为空
      if (chain.isEmpty()) {
         Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
          // 直接反射执行连接点方法
         retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
      }
      else {
         // 包装成一个ReflectiveMethodInvocation
         MethodInvocation invocation =
               new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, 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);
      }
   }
}

4.2 ObjenesisCglibAopProxy

经过上面的处理,我们得到了所有的Callback,也得到了CallbackFilter,在调用方法时,就会经过CallbackFilter的accept方法得到callback的下标,再从callbacks数组中根据下标得到具体callback来执行。

我们来看看AOP中最常用的动态代理拦截器:

DynamicAdvisedInterceptor

@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
   Object oldProxy = null;
   boolean setProxyContext = false;
   Object target = null;
   TargetSource targetSource = this.advised.getTargetSource();
   try {
      if (this.advised.exposeProxy) {
         // 如果需要暴露proxy,则设置到AopContext中
         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<?> targetClass = (target != null ? target.getClass() : null);
      // 获取method所有匹配的Advice
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
      Object retVal;
      // 如果没有匹配的Advice,且是兼容的方法
      if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {
         // 对参数进行处理
         Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
         try {
            // 使用代理方法执行得到返回值
            retVal = methodProxy.invoke(target, argsToUse);
         }
         catch (CodeGenerationException ex) {
            CglibMethodInvocation.logFastClassGenerationFailure(method);
            retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
         }
      }
      else {
         // 如果有匹配的Advice,则进入CGLIB执行方法的特殊逻辑
         retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
      }
      retVal = processReturnType(proxy, target, method, retVal);
      return retVal;
   }
   finally {
      if (target != null && !targetSource.isStatic()) {
         targetSource.releaseTarget(target);
      }
      if (setProxyContext) {
         // Restore old proxy.
         AopContext.setCurrentProxy(oldProxy);
      }
   }
}

对其中的方法进行说明:

  • CglibMethodInvocation.isMethodProxyCompatible

    static boolean isMethodProxyCompatible(Method method) {
       return (Modifier.isPublic(method.getModifiers()) &&
             method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
             !AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method));
    }
    

    公开的,所属类不是Object,不是equals、hashCode、toString的方法就是兼容的方法。

  • AopProxyUtils.adaptArgumentsIfNecessary

    static Object[] adaptArgumentsIfNecessary(Method method, @Nullable Object[] arguments) {
       if (ObjectUtils.isEmpty(arguments)) {
          return new Object[0];
       }
       // 方法参数含有可变参数
       if (method.isVarArgs()) {
          // 参数个数等于arguments中元素数量
          if (method.getParameterCount() == arguments.length) {
             Class<?>[] paramTypes = method.getParameterTypes();
             // 可变参数的index
             int varargIndex = paramTypes.length - 1;
             // 最后一个入参类型
             Class<?> varargType = paramTypes[varargIndex];
             // 最后一个参数是数组类型的(此处为可变参数)
             if (varargType.isArray()) {
                // 获取arguments中对应的参数值
                Object varargArray = arguments[varargIndex];
                // 如果varargArray是一个数组且varargArray不是可变参数对应类型的实例
                if (varargArray instanceof Object[] && !varargType.isInstance(varargArray)) {
                   Object[] newArguments = new Object[arguments.length];
                   // 将arguments中可变参数的值复制到newArguments中,此时newArguments就一个值,这个值是数组类型的
                   System.arraycopy(arguments, 0, newArguments, 0, varargIndex);
                   // 获取可变参数的类型
                   Class<?> targetElementType = varargType.getComponentType();
                   int varargLength = Array.getLength(varargArray);
                   // 创建一个类型为可变内部参数类型,长度为可变参数值个数的数组
                   Object newVarargArray = Array.newInstance(targetElementType, varargLength);
                   // 复制可变参数值到newVarargArray中,此时newVarargArray元素个数为可变参数值个数
                   System.arraycopy(varargArray, 0, newVarargArray, 0, varargLength);
                   newArguments[varargIndex] = newVarargArray;
                   return newArguments;
                }
             }
          }
       }
       return arguments;
    }
    
  • new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed()

    这里分为两部分,首先是创建一个CglibMethodInvocation对象,其次调用其proceed方法。

    public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
    		Object[] arguments, @Nullable Class<?> targetClass,
    		List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
    	// 调用父类方法将传入的值设置进实例的变量中
    	super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
    
    	// 赋值methodProxy
    	this.methodProxy = (isMethodProxyCompatible(method) ? methodProxy : null);
    }
    
    public Object proceed() throws Throwable {
       // 如果当前正在执行的拦截方法是列表的最后一个,那说明应该去指定joinPoint
       if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
          return invokeJoinpoint();
       }
    
       // currentInterceptorIndex初始值为-1,这里最开始是获取的第一个拦截方法
       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 {
             // 方法未匹配上,则跳过当前拦截器,并执行拦截链中下一个拦截器
             return proceed();
          }
       }
       else {
          // 如果是一个拦截器,则直接执行
          return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
       }
    }
    

    在这里,就会执行@Before、@After、@Around等注解的方法。

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值