优秀的编程知识分享平台

网站首页 > 技术文章 正文

Spring源码系列(六)(spring源码深度解析(第2版))

nanyue 2024-07-18 03:55:34 技术文章 7 ℃

一、简介

aop(面向切面编程)是对oop(面向对象编程)的补充和完善。它是利用一种被称为“横切”的技术,解剖开封装的对象的内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并命名为“Aspect”,即切面。所谓的切面,简单的说就是那些与业务无关,却为业务模块所共同调用的逻辑代码封装起来,便于减少系统的重复代码,降低代码之间的耦合,并有利于未来的可操作性和可维护性。

aop的核心概念

1、横切关注点:对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点

2、切面(Aspect):类是对物体特征的抽象,切面就是对横切关注点的抽象

3、连接点(joinpoint):被拦截到的点,因为Spring只支持方法类型的的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器

4、切入点(pointcut):对连接点进行拦截的定义

5、通知(advice):通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类

6、目标对象:代理的目标对象

7、织入(weave):将切面应用到目标对象并导致代理对象构建的过程

8、引入(introduction):在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段

二、实现原理

Spring中aop代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,aop代理可以直接使用容器中的其他bean实例作为目标,这种关系可由IOC容器的依赖注入提供。Spring创建代理的规则是:

1、默认使用java动态代理来创建aop代理,这样就可以为任何接口实例创建代理了。

2、当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可以强制使用CGLIB。

创建aop对象实例是从refresh()方法中的registerBeanPostProcessors()方法为入口。但是在这之前也已经向容器中注入了AnnotationAwareAspectJAutoProxyCreator。

通过代码实例来解释说明AOP的原理和类之间的关系。

配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;


@Configuration
@EnableAspectJAutoProxy
public class MainConfig {
    @Bean
    Calculate calculate() {
        return new MyCalculate();
    }
    @Bean
    MyLogAspect myLogAspect() {
        return new MyLogAspect();
    }
}

正在上面的配置类中看到增加可EnableAspectJAutoProxy注解,进入这个注解的源码,我们可以看到这个注解引入了AspectJAutoProxyRegistrar类。这个类主要的作用是根据给定的EnableAspectJAutoProxy注释,适当地针对当前BeanDefinitionRegistry注册一个AnnotationAwareAspectJAutoProxyCreator。主要是为了完成AnnotationAwareAspectJAutoProxyCreator的注册,这个类的主要作用是aop切面代理创建。

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


   boolean proxyTargetClass() default false;
 
   boolean exposeProxy() default false;


}


class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
   @Override
   public void registerBeanDefinitions(
         AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {


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

定义一个计算接口类作为模板类。

package com.spring.source.aop;


/**
 * 计算类接口
 * Created by lenovo on 2019/7/1.
 */
public interface Calculate {


    /**
     * 加法
     * @param numA
     * @param numB
     * @return
     */
    int add(int numA,int numB);


    /**
     * 减法
     * @param numA
     * @param numB
     * @return
     */
    int reduce(int numA,int numB);


    /**
     * 乘法
     * @param numA
     * @param numB
     * @return
     */
    int multi(int numA,int numB);


    /**
     * 除法
     * @param numA
     * @param numB
     * @return
     */
    int div(int numA,int numB);


    /**
     * 取模
     * @param numA
     * @param numB
     * @return
     */
    int mod(int numA,int num

实现此接口的类

package com.spring.source.aop;


import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;


/**
 * Created by lenovo on 2019/7/1.
 */


public class MyCalculate implements Calculate {
    @Override
    public int add(int numA, int numB) {
        System.out.println("执行目标方法:add");
        return numA + numB;
    }


    @Override
    public int reduce(int numA, int numB) {
        System.out.println("执行目标方法:reduce");
        return numA - numB;
    }


    @Override
    public int multi(int numA, int numB) {
        System.out.println("执行目标方法:multi");
        return numA * numB;
    }


    @Override
    public int div(int numA, int numB) {
        System.out.println("执行目标方法:div");
        return numA / numB;
    }


    @Override
    public int mod(int numA, int numB) {
        System.out.println("执行目标方法:mod");
        int retVal = ((Calculate)AopContext.currentProxy()).add(numA, numB);
//        int retVal = this.add(numA, numB);
//        return retVal%numA;
        return numA % numB;
  

还定义了一个aop切面的实现类

package com.spring.source.aop;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;


import java.util.Arrays;


/**
 * Created by lenovo on 2019/7/1.
 */
@Aspect
public class MyLogAspect {


    @Pointcut("execution(* com.spring.source.aop.MyCalculate.*(..))")
    public void pointCut(){}


    @Before(value = "pointCut()")
    public void methodBefore(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        System.out.println("执行目标方法["+methodName+"]之前执行<前置通知>,入参" + Arrays.asList(joinPoint.getArgs()));
    }


    @After(value = "pointCut()")
    public void methodAfter(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        System.out.println("执行目标方法["+methodName+"]之前执行<后置通知>,入参" + Arrays.asList(joinPoint.getArgs()));
    }


    @AfterReturning(value = "pointCut()")
    public void methodReturn(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        System.out.println("执行目标方法["+methodName+"]之前执行<返回通知>,入参" + Arrays.asList(joinPoint.getArgs()));
    }


    @AfterThrowing(value = "pointCut()")
    public void methodAfterThrowing(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        System.out.println("执行目标方法["+methodName+"]之前执行<异常通知>,入参" + Arrays.asList(joinPoint.getArgs()));
    }


    @Around(value = "pointCut()")
    public Object methodAround(ProceedingJoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        System.out.println(joinPoint.getTarget().getClass().getName());
        System.out.println(joinPoint.getSignature().getClass().getName());
        System.out.println("执行目标方法["+methodName+"]之前执行<环绕通知>,入参" + Arrays.asList(joinPoint.getArgs()));
        //调用目标方法
        Object sum = null;
        try {
            sum =  joinPoint.proceed(joinPoint.getArgs());
        } catch (Throwable throwable) {
            System.out.println("调用目标方法异常:"+throwable.getMessage());
            throwable.printStackTrace();
        }
        return sum;

根据上面的实例代码,画出AOP的源代码流程图。

前面的容器初始化,加载配置、后置处理器前面已经详细的介绍过,这里就不再详细的赘述。

理解AOP先从EnableAspectJAutoProxy注解说起,先看EnableAspectJAutoProxy注解。

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


   //是否启用CGLIB动态代理,默认使用JDK代理
   boolean proxyTargetClass() default false;


   //是否向外暴漏动态代理的对象
   boolean exposeProxy() default false;


在EnableAspectJAutoProxy注解上导入了AspectJAutoProxyRegistrar类,这个类是实现了ImportBeanDefinitionRegistrar接口,凡是实现了这个接口的类都可以给我们的容器中添加bean定义。这个类的作用是往容器中注册了一个名称为org.springframework.aop.config.internalAutoProxyCreator,类型为AnnotationAwareAspectJAutoProxyCreator的注解Aspectj自动代理创建器。

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {


   // 注册 ,增强,配置切面自动代理创建器
   @Override
   public void registerBeanDefinitions(
         AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {


   //往容器中注册对应的aspectj注解自动代理创建器  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);
         }
      }
   }


}


public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
   return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
//注册一个AnnotationAwareAspectJAutoProxyCreator(注解适配的切面自动创建器)
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
      BeanDefinitionRegistry registry, @Nullable Object source) {


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


private static BeanDefinition registerOrEscalateApcAsRequired(


Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {


 


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


//判断容器中有没有org.springframework.aop.config.internalAutoProxyCreator 名称的bean定义


if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {


BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);


if (!cls.getName().equals(apcDefinition.getBeanClassName())) {


int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());


int requiredPriority = findPriorityForClass(cls);


if (currentPriority < requiredPriority) {


apcDefinition.setBeanClassName(cls.getName());


}


}


return null;


}


//容器中没有 那么就注册一个名称叫org.springframework.aop.config.internalAutoProxyCreator  类型是AnnotationAwareAspectJAutoProxyCreator的bean定义


 


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

2、现在分析AnnotationAwareAspectJAutoProxyCreator,先看此类的继承关系

AnnotationAwareAspectJAutoProxyCreator是实现了BeanFactoryAware接口。AbstractAutoProxyCreator实现了BeanFactoryAware接口,AbstractAutoProxyCreator类的setBeanFactory()方法没有做什么,但是子类AbstractAdvisorAutoProxyCreator覆盖了这个方法。

public void setBeanFactory(BeanFactory beanFactory) {
//调用父类方法
   super.setBeanFactory(beanFactory);
   if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
      throw new IllegalArgumentException(
            "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
   }
   //初始化bean工厂方法
   initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}

AnnotationAwareAspectJAutoProxyCreator类覆盖了initBeanFactory()方法,

//创建一个AOP的增强器通过@ApesctJ注解的方式
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//调用父类的方法
   super.initBeanFactory(beanFactory);
   //若aspectj的增强器工厂对象为空,就创建一个ReflectiveAspectJAdvisorFactory
   if (this.aspectJAdvisorFactory == null) {
      this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
   }
   //不为空,就把AspectJAdvisorFactory包装为BeanFactoryAspectJAdvisorsBuilderAdapter
   this.aspectJAdvisorsBuilder =
         new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}

AnnotationAwareAspectJAutoProxyCreator实现了BeanFactoryAware,做了两件事情:

(1)、把BeanFactory保存到AnnotationAwareAspectJAutoProxyCreator组件上

(2)、为AnnotationAwareAspectJAutoProxyCreator的aspectJAdvisorsBuilder aspect增强器赋值。

AnnotationAwareAspectJAutoProxyCreator还实现了BeanPostProcessor接口(后置处理器特性)

public Object postProcessBeforeInitialization(Object bean, String beanName) {
   return bean;
}
//这个方法很重要,创建真正的代理对象
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (this.earlyProxyReferences.remove(cacheKey) != bean) {
      //包装bean,真正的创建代理对象逻辑
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

refresh()方法中的finishBeanFactoryInitialization()方法开始。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // 初始化此上下文服务.
   if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
      beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
   }


   //如果没有bean的后置处理器,注册一个默认的嵌入的解析器
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }


   // 尽早初始化LoadTimeWeaverAware bean,以便尽早注册它们的转换器.
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {
      getBean(weaverAwareName);
   }


   // 停止使用临时类加载器进行类型匹配
   beanFactory.setTempClassLoader(null);


   //允许缓存所有bean定义,不期待进一步的变化
   beanFactory.freezeConfiguration();




   //初始化所有非懒加载剩余的单例
   beanFactory.preInstantiateSingletons

加载所有的剩余非懒加载的单例

public void preInstantiateSingletons() throws BeansException {
   if (logger.isTraceEnabled()) {
      logger.trace("Pre-instantiating singletons in " + this);
   }


   // 获取缓存中beanName
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);


   //触发所有非懒加载初始化 
   for (String beanName : beanNames) {
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         if (isFactoryBean(beanName)) {
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
               final FactoryBean<?> factory = (FactoryBean<?>) bean;
               boolean isEagerInit;
               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                  isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                              ((SmartFactoryBean<?>) factory)::isEagerInit,
                        getAccessControlContext());
               }
               else {
                  isEagerInit = (factory instanceof SmartFactoryBean &&
                        ((SmartFactoryBean<?>) factory).isEagerInit());
               }
               if (isEagerInit) {
                  getBean(beanName);
               }
            }
         }
         else {
         //获取bean
            getBean(beanName);
         }
      }
   }


   //触发所有可以使用bean的后置初始化回调
   for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
      if (singletonInstance instanceof SmartInitializingSingleton) {
         final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else {
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }

AbstractBeanFactory类中获取bean的方法getBean()

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {


   final String beanName = transformedBeanName(name);
   Object bean;


   // Eagerly check singleton cache for manually registered singletons.
   Object sharedInstance = getSingleton(beanName);
   if (sharedInstance != null && args == null) {
      if (logger.isTraceEnabled()) {
         if (isSingletonCurrentlyInCreation(beanName)) {
            logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                  "' that is not fully initialized yet - a consequence of a circular reference");
         }
         else {
            logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
         }
      }
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
   }


   else {
      // Fail if we're already creating this bean instance:
      // We're assumably within a circular reference.
      if (isPrototypeCurrentlyInCreation(beanName)) {
         throw new BeanCurrentlyInCreationException(beanName);
      }


      // Check if bean definition exists in this factory.
      BeanFactory parentBeanFactory = getParentBeanFactory();
      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
         // Not found -> check parent.
         String nameToLookup = originalBeanName(name);
         if (parentBeanFactory instanceof AbstractBeanFactory) {
            return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                  nameToLookup, requiredType, args, typeCheckOnly);
         }
         else if (args != null) {
            // Delegation to parent with explicit args.
            return (T) parentBeanFactory.getBean(nameToLookup, args);
         }
         else if (requiredType != null) {
            // No args -> delegate to standard getBean method.
            return parentBeanFactory.getBean(nameToLookup, requiredType);
         }
         else {
            return (T) parentBeanFactory.getBean(nameToLookup);
         }
      }


      if (!typeCheckOnly) {
         markBeanAsCreated(beanName);
      }


      try {
         final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         checkMergedBeanDefinition(mbd, beanName, args);


         // Guarantee initialization of beans that the current bean depends on.
         String[] dependsOn = mbd.getDependsOn();
         if (dependsOn != null) {
            for (String dep : dependsOn) {
               if (isDependent(beanName, dep)) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
               }
               registerDependentBean(dep, beanName);
               try {
                  getBean(dep);
               }
               catch (NoSuchBeanDefinitionException ex) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
               }
            }
         }


         // Create bean instance.
         if (mbd.isSingleton()) {
            sharedInstance = getSingleton(beanName, () -> {
               try {
                  return createBean(beanName, mbd, args);
               }
               catch (BeansException ex) {
                  // Explicitly remove instance from singleton cache: It might have been put there
                  // eagerly by the creation process, to allow for circular reference resolution.
                  // Also remove any beans that received a temporary reference to the bean.
                  destroySingleton(beanName);
                  throw ex;
               }
            });
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
         }


         else if (mbd.isPrototype()) {
            // It's a prototype -> create a new instance.
            Object prototypeInstance = null;
            try {
               beforePrototypeCreation(beanName);
               prototypeInstance = createBean(beanName, mbd, args);
            }
            finally {
               afterPrototypeCreation(beanName);
            }
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
         }


         else {
            String scopeName = mbd.getScope();
            final Scope scope = this.scopes.get(scopeName);
            if (scope == null) {
               throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
            }
            try {
               Object scopedInstance = scope.get(beanName, () -> {
                  beforePrototypeCreation(beanName);
                  try {
                     return createBean(beanName, mbd, args);
                  }
                  finally {
                     afterPrototypeCreation(beanName);
                  }
               });
               bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
            }
            catch (IllegalStateException ex) {
               throw new BeanCreationException(beanName,
                     "Scope '" + scopeName + "' is not active for the current thread; consider " +
                     "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                     ex);
            }
         }
      }
      catch (BeansException ex) {
         cleanupAfterBeanCreationFailure(beanName);
         throw ex;
      }
   }


   // Check if required type matches the type of the actual bean instance.
   if (requiredType != null && !requiredType.isInstance(bean)) {
      try {
         T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
         if (convertedBean == null) {
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
         }
         return convertedBean;
      }
      catch (TypeMismatchException ex) {
         if (logger.isTraceEnabled()) {
            logger.trace("Failed to convert bean '" + name + "' to required type '" +
                  ClassUtils.getQualifiedName(requiredType) + "'", ex);
         }
         throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
      }
   }
   return (T) bean;
}


@Override
public boolean containsBean(String name) {
   String beanName = transformedBeanName(name);
   if (containsSingleton(beanName) || containsBeanDefinition(beanName)) {
      return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
   }
   // Not found -> check parent.
   BeanFactory parentBeanFactory = getParentBeanFactory();
   return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName

AbstractAutowireCapableBeanFactory类的createBean()方法,创建一个bean实例

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {


   if (logger.isTraceEnabled()) {
      logger.trace("Creating instance of bean '" + beanName + "'");
   }
   RootBeanDefinition mbdToUse = mbd;


   //确认bean的类在此时已经被解析,并且复制那些不能保存在共享的bean定义
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }
   try {
      mbdToUse.prepareMethodOverrides();
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }


   try {
      //给bean的后置处理器一个机会,返回目标bean实例的代理
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
         return bean;
      }
   }
   catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }


   try {
   //创建bean
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isTraceEnabled()) {
         logger.trace("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
   }
   catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
   

AbstractAutowireCapableBeanFactory类的resolveBeforeInstantiation()方法应用实例化前后置处理器,解析是否有实例化前快捷方式的指定bean。

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
   Object bean = null;
   if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
      //确认bean类在此处真正被解析过
      if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
         Class<?> targetType = determineTargetType(beanName, mbd);
         if (targetType != null) {
         //实例化前的后置处理器
            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
            if (bean != null) {
            //实例化后的后置处理器
               bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
            }
         }
      }
      mbd.beforeInstantiationResolved = (bean != null);
   }
   return bean;
}

AbstractAutowireCapableBeanFactory类的applyBeanPostProcessorsBeforeInstantiation()方法把InstantiationAwareBeanPostProcessors处理器应用到制定的bean定义上,激活他们的postProcessBeforeInstantiation方法。

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
   //判断容器中是否有InstantiationAwareBeanPostProcessor
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
         if (result != null) {
            return result;
         }
      }
   }
   return null;
}

AbstractAutoProxyCreator类的postProcessBeforeInstantiation()方法,实例化之前进行后置处理

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
   Object cacheKey = getCacheKey(beanClass, beanName);
//判断TargetSource缓存中是否包含当前bean,如果不包含,则判断当前的bean是否是已经被代理的bean,如果代理过,则不对当前传入的bean进行处理,如果没有代理过,则判断当前bean是否为系统bean,或者是切面逻辑不会包含的bean,如果是,则将当前bean缓存到advisedBeans中,否则继续往下执行。经过这一步的处理之后,只有在TargetSource中没有进行缓存,并且应该被切面逻辑环绕,但是目前还未生成代理对象的bean才会通过此方法
   if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
      if (this.advisedBeans.containsKey(cacheKey)) {
         return null;
      }
      //若是基础的class||是否应该跳过
      if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
      //把cacheKey存放在advisedBeans中
         this.advisedBeans.put(cacheKey, Boolean.FALSE);
         return null;
      }
   }




   // 获取封装当前bean的TargetSource对象,如果不存在,则直接退出当前方法;否则从TargetSource中获取当前bean对象,并且判断是否需要将切面逻辑应用在当前bean上。
   TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
   if (targetSource != null) {
      if (StringUtils.hasLength(beanName)) {
         this.targetSourcedBeans.add(beanName);
      }
      //获取能够对当前bean应用的通知和增强器
      Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
      //根据切面逻辑生成当前bean的代理对象
      Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   }
  return null;
  

AbstractAutoProxyCreator类的isInfrastructureClass()方法,返回给定的bean类是否表示永远不应该代理的基础设置类。默认将实现advice、advisor和AopInfrastructureBeans作为基础设施类。

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

AspectJAwareAdvisorAutoProxyCreator类的shouldSkip()方法,如果这个后处理器考虑使用给定的bean进行自动代理,则子类应该覆盖此方法并返回true。

protected boolean shouldSkip(Class<?> beanClass, String beanName) {
 
   //通过缓存的切面名称列表,进行优化
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   for (Advisor advisor : candidateAdvisors) {
      if (advisor instanceof AspectJPointcutAdvisor &&
            ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
         return true;
      }
   }
   return super.shouldSkip(beanClass, beanName);
}

AnnotationAwareAspectJAutoProxyCreator类的findCandidateAdvisors()方法,找出候选的增强器。

protected List<Advisor> findCandidateAdvisors() {
   // 根据父类规则找到所有的用于动态代理的增强器
   List<Advisor> advisors = super.findCandidateAdvisors();
   //在bean工厂中为所有的AspectJ切面构建增强器
   
   if (this.aspectJAdvisorsBuilder != null) {
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   }
   return advisors;
}

BeanFactoryAspectJAdvisorsBuilder类的buildAspectJAdvisors()方法,在bean工程中找到所有的AspectJ注解切面,并且把切面转化为增强器。此方法第一步先从增强器缓存中获取增强器对象,判断缓存中有没有增强器对象,如果有,那么直接从缓存中获取然后返回。如果没有,从容器中获取所有的beanName,遍历上一步获取所有的beanName,通过beanName获取beanType,根据beanType判断当前bean是否是一个AspectJ注解类,若不是不做任何处理。

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<>();
            //从容器中获取所有bean的name
            String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                  this.beanFactory, Object.class, true, false);
            //遍历beanNames
            for (String beanName : beanNames) {
               if (!isEligibleBean(beanName)) {
                  continue;
               }
               // 根据beanName获取bean的类型
               Class<?> beanType = this.beanFactory.getType(beanName);
               if (beanType == null) {
                  continue;
               }
               检查beanType是否包含Aspectj
               if (this.advisorFactory.isAspect(beanType)) {
                  aspectNames.add(beanName);
                  //创建一个AspectJ类的源信息对象
                  AspectMetadata amd = new AspectMetadata(beanType, beanName);
                  if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
           //根据bean工厂和bean name创建BeanFactoryAspectInstanceFactory
                     MetadataAwareAspectInstanceFactory factory =
                           new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
           //从有Aspectj注解的类中获取通知器          
                     List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                     if (this.beanFactory.isSingleton(beanName)) {
                        this.advisorsCache.put(beanName, classAdvisors);
                     }
                     else {
                        this.aspectFactoryCache.put(beanName, factory);
                     }
                     advisors.addAll(classAdvisors);
                  }
                  else {
                     // Per target or per this.
                     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<>();
   for (String aspectName : aspectNames) {
      List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
      if (cachedAdvisors != null) {
         advisors.addAll(cachedAdvisors);
      }
      else {
         MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
        // 调用advisorFactory.getAdvisors获取通知器
         advisors.addAll(this.advisorFactory.getAdvisors(factory));
      }
   }
   return advisors;
}

ReflectiveAspectJAdvisorFactory类中getAdvisors()方法获取增强器。

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
//获取标识了AspectJ注解的切面类
   Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
   //获取切面的名称
   String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
   validate(aspectClass);


   // 包装MetadataAwareAspectInstanceFactory
   MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
         new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);


   List<Advisor> advisors = new ArrayList<>();
   //获取所有切面类中所有通知方法,除了Pointcut注解的方法
   for (Method method : getAdvisorMethods(aspectClass)) {
   //获取方法的增强器
      Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
      if (advisor != null) {
         advisors.add(advisor);
      }
   }


  
   if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
      Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
      advisors.add(0, instantiationAdvisor);
   }


 
   for (Field field : aspectClass.getDeclaredFields()) {
      Advisor advisor = getDeclareParentsAdvisor(field);
      if (advisor != null) {
         advisors.add(advisor);
      }
   }


   return advisors

ReflectiveAspectJAdvisorFactory类的getAdvisor()方法获取具体的增强器。

public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
      int declarationOrderInAspect, String aspectName) {


   validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//获取aspectj的切点表达式
   AspectJExpressionPointcut expressionPointcut = getPointcut(
         candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
   if (expressionPointcut == null) {
      return null;
   }
//创建advisor实现类
   return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
         this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

通过InstantiationModelAwarePointcutAdvisorImpl的构造方法创建Advisor的实现类。

public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
      Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
      MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {


   this.declaredPointcut = declaredPointcut;
   this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
   this.methodName = aspectJAdviceMethod.getName();
   this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
   this.aspectJAdviceMethod = aspectJAdviceMethod;
   this.aspectJAdvisorFactory = aspectJAdvisorFactory;
   this.aspectInstanceFactory = aspectInstanceFactory;
   this.declarationOrder = declarationOrder;
   this.aspectName = aspectName;


   if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
     
      Pointcut preInstantiationPointcut = Pointcuts.union(
            aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);


      //使其成为动态的,必须从预实例化状态改变为后置实例化状态
      this.pointcut = new PerTargetInstantiationModelPointcut(
            this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
      this.lazy = true;
   }
   else {
    
      this.pointcut = this.declaredPointcut;
      this.lazy = false;
    //实例化增强器
      this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
   }

InstantiationModelAwarePointcutAdvisorImpl类的instantiateAdvice()方法中调用了ReflectiveAspectJAdvisorFactory类中的getAdvice()方法切面对象和增强器。

public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
      MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//获取候选的切面类
   Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
   validate(candidateAspectClass);
//获取切面注解
   AspectJAnnotation<?> aspectJAnnotation =
         AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
   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()) {
      case AtPointcut://是切点返回null
         if (logger.isDebugEnabled()) {
            logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
         }
         return null;
      case AtAround://环绕通知
         springAdvice = new AspectJAroundAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         break;
      case AtBefore://前置通知
         springAdvice = new AspectJMethodBeforeAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         break;
      case AtAfter://后置通知
         springAdvice = new AspectJAfterAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         break;
      case AtAfterReturning://返回通知
         springAdvice = new AspectJAfterReturningAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
         if (StringUtils.hasText(afterReturningAnnotation.returning())) {
            springAdvice.setReturningName(afterReturningAnnotation.returning());
         }
         break;
      case AtAfterThrowing://异常通知
         springAdvice = new AspectJAfterThrowingAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
         if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
            springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
         }
         break;
      default:
         throw new UnsupportedOperationException(
               "Unsupported advice type on method: " + candidateAdviceMethod);
   }


   //配置通知
   springAdvice.setAspectName(aspectName);
   springAdvice.setDeclarationOrder(declarationOrder);
   //获取方法的参数列表
   String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
   if (argNames != null) {
   //为切面设置参数
      springAdvice.setArgumentNamesFromStringArray(argNames);
   }
   springAdvice.calculateArgumentBindings();


   return springAdvice

至此把aop相关的通知,增强器等都注入到了容器中,并且有的已经创建了代理。如果没有创建代理,在调用对用方法的时候也会创建代理,下一小节中具体分析实现的源代码。

三、小结

aop注入容器,创建代理的过程。

Tags:

最近发表
标签列表