Spring5.0源码深度解析之Spring IOC加载

前言

Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器。

Demo:

配置类

/**
 * @Author: klm
 * @Date: 2020/11/6 23:46
 * @Description:
 */
@Configuration
@ComponentScan("com.dream.sunny")
public class SunnyConfig {
}

Bean: SunnyEntity

/**
 * @Author: klm
 * @Date: 2020/11/7 23:30
 * @Description:
 */
@Component
public class SunnyEntity {

   private Integer id;
   private String name;


   public Integer getId() {
      return id;
   }

   public void setId(Integer id) {
      this.id = id;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   @Override
   public String toString() {
      return "SunnyEntity{" +
            "id=" + id +
            ", name='" + name + '\'' +
            '}';
   }
}

启动类

/**
 * @Author: klm
 * @Date: 2020/11/7 23:49
 * @Description:
 */
public class MyStart {
   public static void main(String[] args) {
      ApplicationContext context = new AnnotationConfigApplicationContext(SunnyConfig.class);

      UserServiceImpl bean = context.getBean(UserServiceImpl.class);
      bean.sayHi();

      SunnyEntity sunnyEntity = (SunnyEntity) context.getBean("sunnyEntity");
      System.out.println(sunnyEntity);
   }
}

Spring IOC加载流程分析开始

1.实例化AnnotationConfigApplicationContext容器

我们先从 AnnotationConfigApplicationContext 出发

ApplicationContext context = new AnnotationConfigApplicationContext(SunnyConfig.class);

我们先看一下AnnotationConfigApplicationContext 的类图关系


Spring5.0源码深度解析之Spring IOC加载_第1张图片

看完它的类图后,我们跟进它的构造方法中去

/**
 * Create a new AnnotationConfigApplicationContext, deriving bean definitions
 * from the given component classes and automatically refreshing the context.
 *
 * @param componentClasses one or more component classes — for example,
 *                         {@link Configuration @Configuration} classes
 */
 //根据参数类型可以得知,我们可能传入多个配置类
public AnnotationConfigApplicationContext(Class... componentClasses) {
   //调用构造函数,this():调用本身构造函数,但是如果有父类的话,会先走父类的构造函数,再走子类的构造函数
   this();

   //注册配置类(将配置类注册到Bean定义中)
   register(componentClasses);

   //IOC容器刷新接口
   refresh();
}

我们先对这个构造方法做一个简单的了解
1.从该构造方法的传入参数可以得知,我们可以传入很多个配置类,当然不过一般情况下,只会传入一个配置类
2.当然这个配置有两种说法
a.如果给配置类加了@Configurtion注解,那么在Sping容器里面会默认它为Full配置类
b.如果没有给配置类加@Configurtion注解,那么在Spring容器里面则认为它是Lite类,有些地方也把Lite类称之为普通Bean

2.初始化Bean工厂

接着我们进入this()来调用本类的无参构造方法

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

   private final AnnotatedBeanDefinitionReader reader;

   //类路径下Bean定义扫描器
   private final ClassPathBeanDefinitionScanner scanner;


   /**
    * Create a new AnnotationConfigApplicationContext that needs to be populated
    * through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
    */
   public AnnotationConfigApplicationContext() {
      //这里继承了GenericApplicationContext类,在走本身的构造方法之前,会先走父类的构造方法

      //从单词字面意思理解就是:创建一个注解的Bean定义读取器
      //什么是Bean定义? BeanDefinition
      // 就是定义Bean的规范,以便后面的Bean注册 (完成了spring内部BeanDefinition的注册(主要是后置处理器))
      //
      // 读取所有配置类
      this.reader = new AnnotatedBeanDefinitionReader(this);


      /**
       * 定义Bean扫描(其实就是扫描包的地方)
       *
       * 创建BeanDefinition扫描器
       * 可以用来扫描包或者类,继而转换为Bean定义
       *
       * spring默认的扫描包不是这个scanner对象
       * 而是自己new的一个ClassPathBeanDefinitionScanner
       * spring在执行工程后置处理器ConfigurationClassPostProcessor时,去扫描包时会new一个ClassPathBeanDefinitionScanner
       *
       * 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
       *
       */
      this.scanner = new ClassPathBeanDefinitionScanner(this);
   }
}

AnnotationConfigApplicationContext类是有继承关系的,会隐式调用父类的构造方法。
执行它无参构造方法,会先执行父类的构造方法,也就是先跳到GenericApplicationContext类,执行它的无参构造方法,然后初始化BeanFactory容器,因为该容器是生产我们的Bean对象的,所以必须在初始化的时候加载

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {

   private final DefaultListableBeanFactory beanFactory;

   @Nullable
   private ResourceLoader resourceLoader;

   private boolean customClassLoader = false;

   private final AtomicBoolean refreshed = new AtomicBoolean();


   /**
    * Create a new GenericApplicationContext.
    *
    * @see #registerBeanDefinition
    * @see #refresh
    */
   public GenericApplicationContext() {

      //为ApplicationContext上下文 初始化BeanFactory对象(实例化Bean工厂)
      //可能会觉得有点疑惑,为啥是DefaultListableBeanFactory,因为这个是子类啊,最底层的实现,子类继承了父类的所有方法呢,所以更加强大呢
      //可以查看DefaultListableBeanFactory它的类图即可明白
      this.beanFactory = new DefaultListableBeanFactory();
   }
}

那么可能有疑问,为什么是new DefaultListableBeanFactory() 而 不是直接使用BeanFactory接口?
我们来看下DefaultListableBeanFactory它的类图就明白了
1.我们可以看到BeanFactory它是一个顶层的接口,下面还有很多其他的工厂实现顶层工厂并进行增强, 但是通过类图得知DefaultListableBeanFactory实现了BeanFactory以及它的子工厂的所有功能,所以更加的强大,且拥有生产Bean的能力
2.并且它实现了BeanDefinitionRegistry接口,该接口的作用就是能够注册Bean定义,而实现了它,DefaultListableBeanFactory也拥有了注册Bean定义的功能
所以这就是为什么,在初始化BeanFactory用的是DefaultListableBeanFactory方法了

Spring5.0源码深度解析之Spring IOC加载_第2张图片

3.初始化Bean定义读取器

接着我们回到AnnotationConfigApplicationContext类中的this()方法
看到如下代码

this.reader = new AnnotatedBeanDefinitionReader(this);

该行代码主要做了两个事情
1.注册内置BeanPostProcessor
2.注册相关的BeanDefinition

我们跟进AnnotatedBeanDefinitionReader方法,来看看Spring初始化读取都做了些什么
这里的BeanDefinitionRegistry当然就是AnnotationConfigApplicationContext的实例了,这里又直接调用了此类其他的构造方法

/**
 * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry.
 * 

If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext}, * the {@link Environment} will be inherited, otherwise a new * {@link StandardEnvironment} will be created and used. * @param registry the {@code BeanFactory} to load bean definitions into, * in the form of a {@code BeanDefinitionRegistry} * @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment) * @see #setEnvironment(Environment) */ public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { this(registry, getOrCreateEnvironment(registry)); }

让我们把目光移动到这个方法的最后一行,进入registerAnnotationConfigProcessors方法

/**
 * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry,
 * using the given {@link Environment}.
 * @param registry the {@code BeanFactory} to load bean definitions into,
 * in the form of a {@code BeanDefinitionRegistry}
 * @param environment the {@code Environment} to use when evaluating bean definition
 * profiles.
 * @since 3.1
 */
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
   Assert.notNull(environment, "Environment must not be null");

   //把ApplicationContext对象赋值给AnnotatedBeanDefinitionReader
   this.registry = registry;
   //用户处理条件注解 @Conditional os.name
   this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
   //注册一些内置的后置处理器
   AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

这又是一个门面方法,再点进去

/**
 * Register all relevant annotation post processors in the given registry.
 *
 * @param registry the registry to operate on
 */
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
   registerAnnotationConfigProcessors(registry, null);
}

registerAnnotationConfigProcessors这个方法的返回值Set,但是上游方法并没有去接收这个返回值,所以这个方法的返回值也不是很重要了,当然方法内部给这个返回值赋值也不重要了。
由于这个方法内容比较多,这里就把最核心的贴出来,这个方法的核心就是注册Spring内置的多个Bean

/**
 * Register all relevant annotation post processors in the given registry.
 *
 * @param registry the registry to operate on
 * @param source   the configuration source element (already extracted)
 *                 that this registration was triggered from. May be {@code null}.
 * @return a Set of BeanDefinitionHolders, containing all bean definitions
 * that have actually been registered by this call
 */
public static Set registerAnnotationConfigProcessors(
      BeanDefinitionRegistry registry, @Nullable Object source) {

   DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
   if (beanFactory != null) {
      if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
         //注册了实现Order接口的排序器
         beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
      }

      //设置@AutoWired的候选的解析器:ContextAnnotationAutowireCandidateResolver
      // getLazyResolutionProxyIfNecessary方法,它也是唯一实现。
      //如果字段上带有@Lazy注解,表示进行懒加载 Spring不会立即创建注入属性的实例,而是生成代理对象,来代替实例
      if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
         beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
      }
   }

   Set beanDefs = new LinkedHashSet<>(8);

   /**
    * 值:名字叫:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
    * 这个if判断 其实就是将读取到的所有配置类进行解析成Bean定义 然后注册到 BeanDefinitionFactoryMap容器中
    */
   if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   /**
    * 为我们容器中注册了处理@Autowired 注解的处理器AutowiredAnnotationBeanPostProcessor
    * 名字叫:org.springframework.context.annotation.internalAutowiredAnnotationProcessor
    */
   if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   return beanDefs;
}

我们来详细分析如下代码

if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
   RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
   def.setSource(source);
   beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}

1.判断容器中是否存在了 ConfigurationClassPostProcessor Bean
2.如果不存在(当然这里肯定不存在,因为在初始化阶段嘛),然后通过RootBeanDefinition的构造方法获得ConfigurationClassPostProcessor的BeanDedefinition(RootBeanDefinition是BeanDefinition的子类)
3.执行registerPostProcessor方法,registerPostProcessor方法内部就是注册Bean,当然这里注册其他Bean也是一样的流程。
ConfigurationClassPostProcessor类还有个重要的细节点就是 读取我们的配置类并解析 然后注册成Bean定义
这也就是为什么这个类能够解析@componentScan、@ComponentScans以及@import注解的原因啦
(可能会有疑问?为什么要实现BeanFacotryPostProcessor接口,才能进行解析这些注解? 因为该接口非常的灵活,且扩展性很高 BeanFactoryPostProcessor是实现spring容器功能扩展的重要接口,例如修改bean属性值,实现bean动态代理等。很多框架都是通过此接口实现对spring容器的扩展,例如mybatis与spring集成时 )

BeanDefinition是什么?

我们来看看BeanDefinition的类图
向上类图
BeanMetadataElement接口:BeanDefinition元数据,返回该Bean的来源
AttributeAccessor接口:提供对BeanDefinition属性操作能力

Spring5.0源码深度解析之Spring IOC加载_第3张图片

向下类图
它是用来描述Bean的,里面存放着关于Bean的一系列信息,比如Bean的作用域,Bean所对应的Class,是否懒加载,是否Primary等等,这个BeanDefinition也相当重要,我们以后会常常和它打交道。

Spring5.0源码深度解析之Spring IOC加载_第4张图片

然后我们跟进registerPostProcessor()方法
这方法为BeanDefinition设置了一个Role,ROLE_INFRASTRUCTURE代表这是spring内部的,并非用户定义的

private static BeanDefinitionHolder registerPostProcessor(
      BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

   definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
   registry.registerBeanDefinition(beanName, definition);
   return new BeanDefinitionHolder(definition, beanName);
}

然后我们看到registerBeanDefinition()方法,跟进去
发现这个方法是接口里面的,没办法直接点进去,因为接口下实现了很多个方法,首先要知道registry实现类是什么,那么它的实现是什么呢?
答案是:DefaultListableBeanFactory

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {

   Assert.hasText(beanName, "Bean name must not be empty");
   Assert.notNull(beanDefinition, "BeanDefinition must not be null");

   if (beanDefinition instanceof AbstractBeanDefinition) {
      try {
         ((AbstractBeanDefinition) beanDefinition).validate();
      } catch (BeanDefinitionValidationException ex) {
         throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
               "Validation of bean definition failed", ex);
      }
   }

   BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
   if (existingDefinition != null) {
      if (!isAllowBeanDefinitionOverriding()) {
         throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
      } else if (existingDefinition.getRole() < beanDefinition.getRole()) {
         // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
         if (logger.isInfoEnabled()) {
            logger.info("Overriding user-defined bean definition for bean '" + beanName +
                  "' with a framework-generated bean definition: replacing [" +
                  existingDefinition + "] with [" + beanDefinition + "]");
         }
      } else if (!beanDefinition.equals(existingDefinition)) {
         if (logger.isDebugEnabled()) {
            logger.debug("Overriding bean definition for bean '" + beanName +
                  "' with a different definition: replacing [" + existingDefinition +
                  "] with [" + beanDefinition + "]");
         }
      } else {
         if (logger.isTraceEnabled()) {
            logger.trace("Overriding bean definition for bean '" + beanName +
                  "' with an equivalent definition: replacing [" + existingDefinition +
                  "] with [" + beanDefinition + "]");
         }
      }
      this.beanDefinitionMap.put(beanName, beanDefinition);
   } else {
      if (hasBeanCreationStarted()) {
         // Cannot modify startup-time collection elements anymore (for stable iteration)
         synchronized (this.beanDefinitionMap) {
            this.beanDefinitionMap.put(beanName, beanDefinition);
            List updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
            updatedDefinitions.addAll(this.beanDefinitionNames);
            updatedDefinitions.add(beanName);
            this.beanDefinitionNames = updatedDefinitions;
            removeManualSingletonName(beanName);
         }
      } else {
         // Still in startup registration phase
         this.beanDefinitionMap.put(beanName, beanDefinition);
         this.beanDefinitionNames.add(beanName);
         removeManualSingletonName(beanName);
      }
      this.frozenBeanDefinitionNames = null;
   }

   if (existingDefinition != null || containsSingleton(beanName)) {
      resetBeanDefinition(beanName);
   } else if (isConfigurationFrozen()) {
      clearByTypeCache();
   }
}

看到这么多代码,估计大家伙有点晕了,问题不大,我们只关注里面的两行代码即可

//beanDefinitionMap是Map,
//这里就是把beanName作为key,ScopedProxyMode作为value,推到map里面
this.beanDefinitionMap.put(beanName, beanDefinition);

//beanDefinitionNames就是一个List,这里就是把beanName放到List中去
this.beanDefinitionNames.add(beanName);

从这里可以看出DefaultListableBeanFactory就是我们所说的容器了,为什么这么说呢?因为我们跟进去这个方法就是在DefaultListableBeanFactory类中嘛
该类中里面放着全局静态变量beanDefinitionMap,beanDefinitionNames,beanDefinitionMap 他们都是一个ConcurrentHashMap
beanName作为Key,beanDefinition作为Value,beanDefinitionNames是一个集合,里面存放了beanName。
DefaultListableBeanFactory中的beanDefinitionMap,beanDefinitionNames也是相当重要的,以后会经常看到它,最好看到它,第一时间就可以反应出它里面放了什么数据
上面已经介绍过,这里会一连串注册好几个Bean,在这其中最重要的一个Bean(没有之一)就是BeanDefinitionRegistryPostProcessor Bean。
ConfigurationClassPostProcessor实现BeanDefinitionRegistryPostProcessor接口,BeanDefinitionRegistryPostProcessor接口又扩展了BeanFactoryPostProcessor接口,BeanFactoryPostProcessor是Spring的扩展点之一,ConfigurationClassPostProcessor是Spring极为重要的一个类,必须牢牢的记住上面所说的这个类和它的继承关系。

Spring5.0源码深度解析之Spring IOC加载_第5张图片

除了注册了ConfigurationClassPostProcessor,还注册了其他Bean,其他Bean也都实现了其他接口,比如BeanPostProcessor等。
BeanPostProcessor接口也是Spring的扩展点之一。
至此,实例化AnnotatedBeanDefinitionReader reader分析完毕。

4.初始化Bean定义扫描器

接着我们回到AnnotationConfigApplicationContext类中的this()方法
看到如下代码

this.scanner = new ClassPathBeanDefinitionScanner(this);

由于常规使用方式是不会用到AnnotationConfigApplicationContext里面的scanner的,这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法。所以这里就不看scanner是如何被实例化的了。

到这里我们前面的this方法就基本走完了,那大概总结一下this()方法主要实现了那几个步骤 1.初始化BeanFactory:主要实现两个接口,第一个 实现了Bean定义注册,第二个实现了初始化BeanFacotry 2.实例化Bean读取器:在Bean读取器底层会创建很多初始化类,如果不创建这些初始化的类并注册到Bean容器中,那么后面的普通的Bean对象也就无法加载到Spring容器中了 3.实例化Bean扫描器:这里主要扫描某些包下的所有类(例如:@componentScan("扫描包地址"))

5.注册配置类为BeanDefinition

总结完成后,我们回到AnnotationConfigApplicationContext类的的构造方法,接着我们在看到Registry()方法

//注册配置类(将配置类注册到Bean定义中)
register(componentClasses);

我们可以看到传入的参数是可以多个的,也就意味着我们可以传入多个的配置类,但是一般情况下,都是只会传入一个配置类的哈

@Override
public void register(Class... componentClasses) {
   Assert.notEmpty(componentClasses, "At least one component class must be specified");
   this.reader.register(componentClasses);
}

我们在跟进this.reader.register()方法
我们可以看到,它这里循环遍历我们传入的配置类,将我们所有传入的配置类注册成Bean定义

public void register(Class... componentClasses) {
   for (Class componentClass : componentClasses) {
      registerBean(componentClass);
   }
}

继续跟进去registerBean()方法

public void registerBean(Class beanClass) {
   doRegisterBean(beanClass, null, null, null, null);
}

我们来看一下doRegisterBean()注册方法

private  void doRegisterBean(Class beanClass, @Nullable String name,
      @Nullable Class[] qualifiers, @Nullable Supplier supplier,
      @Nullable BeanDefinitionCustomizer[] customizers) {
   //存储@Configuration注解注释的类
   AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
   //判断是否需要跳过注解,spring中有一个@Condition注解,当不满足条件,这个bean就不会被解析
   if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
      return;
   }

   abd.setInstanceSupplier(supplier);
   //解析bean的作用域,如果没有设置的话,默认为单例
   ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
   abd.setScope(scopeMetadata.getScopeName());
   //获得beanName
   String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

   //解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Description
   AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
   if (qualifiers != null) {
      for (Class qualifier : qualifiers) {
         if (Primary.class == qualifier) {
            abd.setPrimary(true);
         }
         else if (Lazy.class == qualifier) {
            abd.setLazyInit(true);
         }
         else {
            abd.addQualifier(new AutowireCandidateQualifier(qualifier));
         }
      }
   }
   if (customizers != null) {
      for (BeanDefinitionCustomizer customizer : customizers) {
         customizer.customize(abd);
      }
   }

   BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
   definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

   //注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册,
   //DefaultListableBeanFactory维护着一系列信息,比如beanDefinitionNames,beanDefinitionMap
   //beanDefinitionNames是一个List,用来保存beanName
   //beanDefinitionMap是一个Map,用来保存beanName和beanDefinition
   BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

在这里又要说明下,以常规方式去注册配置类,此方法中除了第一个参数,其他参数都是默认值。
1.通过AnnotatedGenericBeanDefinition的构造方法,获得配置类的BeanDefinition,这里是不是似曾相似,在注册ConfigurationClassPostProcessor类的时候,也是通过构造方法去获得BeanDefinition的,只不过当时是通过RootBeanDefinition去获得,现在是通过AnnotatedGenericBeanDefinition去获得。
2.判断需不需要跳过注册,Spring中有一个@Condition注解,如果不满足条件,就会跳过这个类的注册。
3.然后是解析作用域,如果没有设置的话,默认为单例。
4.获得BeanName。
5.解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Description。
6.限定符处理,不是特指@Qualifier注解,也有可能是Primary,或者是Lazy,或者是其他(理论上是任何注解,这里没有判断注解的有效性)。
7.把AnnotatedGenericBeanDefinition数据结构和beanName封装到一个对象中(这个不是很重要,可以简单的理解为方便传参)。
8.注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册

接着我们看到最后一行,跟进去
这个registerBeanDefinition是不是又有一种似曾相似的感觉,没错,在上面注册Spring内置的Bean的时候,已经解析过这个方法了,这里就不重复了,
如果此时是debug模式下的话,可以观察下beanDefinitionMap beanDefinitionNames两个静态变量的内容,集合中除了Spring内置的Bean,还有我们传进来的Bean,这里的Bean当然就是我们的配置类了

public static void registerBeanDefinition(
      BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
      throws BeanDefinitionStoreException {

   //获取beanName
   // Register bean definition under primary name.
   String beanName = definitionHolder.getBeanName();

   //注册bean
   registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

   //Spring支持别名
   // Register aliases for bean name, if any.
   String[] aliases = definitionHolder.getAliases();
   if (aliases != null) {
      for (String alias : aliases) {
         registry.registerAlias(beanName, alias);
      }
   }
}
Spring5.0源码深度解析之Spring IOC加载_第6张图片

到这里注册配置类也分析完毕了。
总结:这个方法的主要作用就是 将扫描到的配置类注册成Bean定义,这里仅仅只是注册扫描到的配置类哦~

6. refresh() Bean的生命周期

好啦,总结完成注册方法后,我们继续回到AnnotationConfigApplicationContext类的的构造方法,接着我们在看到本文最重要的一块refresh()方法了

//IOC容器刷新接口
refresh();

其实文章开始到这里,整个前面流程都只是将一些创世纪的类和我们的配置类注册成Bean定义,且Spring并没有去帮我们去实例化这些已经成为Bean定义的Bean
所以接下来分析的refresh()方法,就是来帮你干完剩下来的事情

我们来进入refresh()
refresh()的总体流程如下。

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // 1.做些refresh前的准备工作、例如设置启动时间等
      prepareRefresh();

      //2:重点,刷新beanfactory,配置BeanDefinition
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      //3:对bean工厂进行填充属性
      prepareBeanFactory(beanFactory);

      try {
         // 4:拓展点,由自定义的context去实现,在BeanFactory准备工作完成后做一些定制化的处理 
         postProcessBeanFactory(beanFactory);

         // 5.调用我们的bean工厂的后置处理器. 1. 会在此将class扫描成beanDefinition  2.bean工厂的后置处理器调用
         //BeanFactoryPostProcessors (解析配置类)
         invokeBeanFactoryPostProcessors(beanFactory);

         // 6.注册我们bean的后置处理器
         registerBeanPostProcessors(beanFactory);

         // 7.初始化国际化资源处理器.
         initMessageSource();

         // 8.创建事件多播器
         initApplicationEventMulticaster();

         // 9.这个方法同样也是留个子类实现的springboot也是从这个方法进行启动tomcat的.
         onRefresh();

         //10.把我们的事件监听器注册到多播器上
         registerListeners();

         // 11.实例化剩余的单实例Bean (循环所有的Bean定义,将Bean注册到IOC容器中) 底层实现了getBean方法,实例化Bean对象
         finishBeanFactoryInitialization(beanFactory);

         // 12.最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的)
         finishRefresh();
      } catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // Propagate exception to caller.
         throw ex;
      } finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}

把上述代码的关键流程使用流程图画出来,如图所示:


Spring5.0源码深度解析之Spring IOC加载_第7张图片

里面有很多方法,我们来主要分析两个方法,其他的方法不是本文的重点,这里不过多深究了
1.invokeBeanFactoryPostProcessors()
2.finishBeanFactoryInitialization()

把上述代码的关键流程使用流程图画出来,如图所示:

6.1 prepareRefresh()

从命名来看,就知道这个方法主要做了一些刷新前的准备工作,和主流程关系不大,主要是保存了容器的启动时间,启动标志等。

protected void prepareRefresh() {
   //记录一下启动时间,是一个时间戳
   this.startupDate = System.currentTimeMillis();
   //将applicationContext状态设置非关闭
   this.closed.set(false);
   //将applicationContext状态设置已激活
   this.active.set(true);

   if (logger.isDebugEnabled()) {
      if (logger.isTraceEnabled()) {
         logger.trace("Refreshing " + this);
      } else {
         logger.debug("Refreshing " + getDisplayName());
      }
   }

   //这个是留给子类去实现的,目前没做任何操作
   initPropertySources();

   //这里做了2个工作,一个是创建一个环境对象StandardEnvironment,另一个是校验必须的属性是否在环境变量中存在,不存在就抛异常MissingRequiredPropertiesException
   getEnvironment().validateRequiredProperties();

   //会尽量这里,默认是空
   if (this.earlyApplicationListeners == null) {
      //applicationListeners 为空集合
      this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
   } else {
      //清空applicationListeners集合内容
      this.applicationListeners.clear();
      //重新设置applicationListeners集合内容
      this.applicationListeners.addAll(this.earlyApplicationListeners);
   }

   //收集早期的事件,一旦事件派发器可以使用,就派发这些事件
   this.earlyApplicationEvents = new LinkedHashSet<>();
}

6.2 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()

这个方法和主流程关系也不是很大,可以简单的认为,就是把beanFactory取出来而已。XML模式下会在这里读取BeanDefinition
这里有点深,就不贴代码了

6.3 prepareBeanFactory()

该方法的作用在于对Bean工厂进行初始化或者说给Bean工厂填充属性

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   //设置类加载器,表达式解析器,资源相关的处理器
   beanFactory.setBeanClassLoader(getClassLoader());

   //设置bean表达式解析器
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));

   //属性编辑器支持
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   //添加一个后置处理器:ApplicationContextAwareProcessor,此后置处理处理器实现了BeanPostProcessor接口
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

   //以下接口,忽略自动装配
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
   beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

   //以下接口,允许自动装配,第一个参数是自动装配的类型,,第二个字段是自动装配的值
   beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   //添加一个后置处理器:ApplicationListenerDetector,此后置处理器实现了BeanPostProcessor接口,用于检测内部的的ApplicationListener
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

   // 这个是用于类加载阶段进行AOP切入,而我们平时用的cglib或jdk动态代理是运行期切入
   if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      // Set a temporary ClassLoader for type matching.
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }

   // 向容器中注册了3个环境相关的bean
   if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
   }
}

6.4 postProcessBeanFactory()

该方法是个空方法,可能以后Spring会对其进行扩展吧

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

6.5 invokeBeanFactoryPostProcessors()

调用我们的bean工厂的后置处理器. 1. 会在此将class扫描成beanDefinition 2.bean工厂的后置处理器调用

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   //  获取两处存储BeanFactoryPostProcessor的对象 传入供接下来的调用
   //  1.当前Bean工厂
   //  2.自定义BeanFactoryPostProcessor
   // getBeanFactoryPostProcessors()方法是真的坑,刚开始一直以为这个地方永远都是空集合
   // 到后面才知道,我们可以自己调用annotationConfigApplicationContext.addBeanFactoryPostProcessor(x)添加bean工厂后置处理器
   PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

   // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
   // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
   if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}

让我们来进入第一个方法的第二个参数 getBeanFactoryPostProcessors()方法
这个方法看单词的就知道是获取Bean工厂后置处理器嘛,看到此处,我当时就有点懵逼,既然是要获取bean的后置处理器,这他喵咋直接获取的一个空集合捏。
也没有找到地方入口将值插入,后来才知道可以在外部手动添加后置处理器,而不是由Spring容器去扫描获取

public List getBeanFactoryPostProcessors() {
   return this.beanFactoryPostProcessors;
}

//当点击this.beanFactoryPostProcessors,直接找到的是下面这行代码的空集合了。
private final List beanFactoryPostProcessors = new ArrayList<>();

接着回到上面代码,我们进入invokeBeanFactoryPostProcessors()方法

public static void invokeBeanFactoryPostProcessors(
         ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {

      //调用BeanDefinitionRegistryPostProcessor的后置处理器 Begin
      // 定义已处理的后置处理器
      Set processedBeans = new HashSet<>();

      //判断我们的beanFactory实现了BeanDefinitionRegistry 这里肯定进入if的
      //因为beanFactory是DefaultListableBeanFactory类嘛(不要被参数误导,刚开始初始化beanFactory就是这个类哦),DefaultListableBeanFactory类他是实现了BeanDefinitionRegistry接口的
      if (beanFactory instanceof BeanDefinitionRegistry) {
         //强行把我们的bean工厂转为BeanDefinitionRegistry,因为待会需要注册Bean定义
         BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
         //保存BeanFactoryPostProcessor类型的后置处理器(普通后置处理器)   --> BeanFactoryPostProcessor 提供修改
         List regularPostProcessors = new ArrayList<>();
         //保存BeanDefinitionRegistryPostProcessor类型的后置处理器(Bean定义注册后置处理器)  --> BeanDefinitionRegistryPostProcessor 提供注册
         List registryProcessors = new ArrayList<>();

         // 循环传进来的beanFactoryPostProcessors,正常情况下,beanFactoryPostProcessors肯定没有数据
         // 因为beanFactoryPostProcessors是获得手动添加的,而不是spring扫描的
         // 只有手动调用annotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX)才会有数据
         for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            // 判断postProcessor是不是BeanDefinitionRegistryPostProcessor,因为BeanDefinitionRegistryPostProcessor
            // 扩展了BeanFactoryPostProcessor,所以这里先要判断是不是BeanDefinitionRegistryPostProcessor
            // 是的话,直接执行postProcessBeanDefinitionRegistry方法,然后把对象装到registryProcessors里面去
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
               //进行强制转化
               BeanDefinitionRegistryPostProcessor registryProcessor =
                     (BeanDefinitionRegistryPostProcessor) postProcessor;
               //调用他作为BeanDefinitionRegistryPostProcessor的处理器的后置方法
               registryProcessor.postProcessBeanDefinitionRegistry(registry);
               //添加到我们用于保存的BeanDefinitionRegistryPostProcessor的集合中
               registryProcessors.add(registryProcessor);
            }
            else {//若没有实现BeanDefinitionRegistryPostProcessor 接口,那么他就是BeanFactoryPostProcessor
               //把当前的后置处理器加入到普通后置处理器集合中
               regularPostProcessors.add(postProcessor);
            }
         }

         //定义一个集合用户保存当前准备创建的BeanDefinitionRegistryPostProcessor
         List currentRegistryProcessors = new ArrayList<>();

         //第一步:去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称
         String[] postProcessorNames =
               beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         //循环筛选出来的匹配BeanDefinitionRegistryPostProcessor的类型名称
         for (String ppName : postProcessorNames) {
            //判断是否实现了PriorityOrdered接口的
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
               //显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
               //获得ConfigurationClassPostProcessor类,并且放到currentRegistryProcessors
               //ConfigurationClassPostProcessor是很重要的一个类,它实现了BeanDefinitionRegistryPostProcessor接口
               //BeanDefinitionRegistryPostProcessor接口又实现了BeanFactoryPostProcessor接口
               //ConfigurationClassPostProcessor是极其重要的类
               //里面执行了扫描Bean,Import,ImportResouce等各种操作
               //用来处理配置类(有两种情况 一种是传统意义上的配置类,一种是普通的bean)的各种逻辑
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
               //把name放到processedBeans,后续会根据这个集合来判断处理器是否已经被执行过了
               processedBeans.add(ppName);
            }
         }
         //对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
         sortPostProcessors(currentRegistryProcessors, beanFactory);
         // 把当前的加入到总的里面去
         registryProcessors.addAll(currentRegistryProcessors);
         // 执行 bean 定义注册器后置处理器,它会把 bean 定义注册器中的 bean 定义注册到 bean 工厂去
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
         //调用完之后,清空当前bean 定义注册器处理器列表
         currentRegistryProcessors.clear();
//---------------------------------------调用内置实现PriorityOrdered接口ConfigurationClassPostProcessor完毕--优先级No1-End----------------------------------------------------------------------------------------------------------------------------
         //去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称(内置的和上面注册的)
         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         //循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称
         for (String ppName : postProcessorNames) {
            //表示没有被处理过,且实现了Ordered接口的
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
               //显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
               //同时也加入到processedBeans集合中去
               processedBeans.add(ppName);
            }
         }
         //对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
         sortPostProcessors(currentRegistryProcessors, beanFactory);
         //把他加入到用于保存到registryProcessors中
         registryProcessors.addAll(currentRegistryProcessors);
         //调用他的后置处理方法
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
         //调用完之后,马上clea掉
         currentRegistryProcessors.clear();
//-----------------------------------------调用自定义Order接口BeanDefinitionRegistryPostProcessor完毕-优先级No2-End-----------------------------------------------------------------------------------------------------------------------------
         //调用没有实现任何优先级接口的BeanDefinitionRegistryPostProcessor
         //定义一个重复处理的开关变量 默认值为true
         boolean reiterate = true;
         //第一次就可以进来
         while (reiterate) {
            //进入循环马上把开关变量给改为false
            reiterate = false;
            //去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            //循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称
            for (String ppName : postProcessorNames) {
               //没有被处理过的
               if (!processedBeans.contains(ppName)) {
                  //显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
                  currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                  //同时也加入到processedBeans集合中去
                  processedBeans.add(ppName);
                  //再次设置为true
                  reiterate = true;
               }
            }
            //对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            //把他加入到用于保存到registryProcessors中
            registryProcessors.addAll(currentRegistryProcessors);
            //调用他的后置处理方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            //进行clear
            currentRegistryProcessors.clear();
         }
//-----------------------------------------调用没有实现任何优先级接口自定义BeanDefinitionRegistryPostProcessor完毕--End-----------------------------------------------------------------------------------------------------------------------------
         //调用 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
         invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
         //调用BeanFactoryPostProcessor 自设的(没有)
         invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
      }

      else {
         //若当前的beanFactory没有实现了BeanDefinitionRegistry 说明没有注册Bean定义的能力
         // 那么就直接调用BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
         invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
      }

//-----------------------------------------所有BeanDefinitionRegistryPostProcessor调用完毕--End-----------------------------------------------------------------------------------------------------------------------------


//-----------------------------------------处理BeanFactoryPostProcessor --Begin-----------------------------------------------------------------------------------------------------------------------------

      //获取容器中所有的 BeanFactoryPostProcessor
      String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

      //保存实现了priorityOrdered接口的BeanFactoryPostProcessor
      List priorityOrderedPostProcessors = new ArrayList<>();
      //保存实现了Ordered接口的BeanFactoryPostProcessor
      List orderedPostProcessorNames = new ArrayList<>();
      //保存BeanFactoryPostProcessor没有实现任何优先级接口的 (也就是保存剩下的Bean工厂后置处理器)
      List nonOrderedPostProcessorNames = new ArrayList<>();

      // 过滤掉已经处理过的后置处理器处理器,因为上面已经处理过了一些了
      for (String ppName : postProcessorNames) {
         //processedBeans包含的话,表示在上面处理BeanDefinitionRegistryPostProcessor的时候处理过了
         if (processedBeans.contains(ppName)) {
            // skip - already processed in first phase above
         }
         //判断是否实现了PriorityOrdered 优先级最高
         else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
         }
         //判断是否实现了Ordered  优先级 其次
         else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
         }
         //没有实现任何的优先级接口的  最后调用
         else {
            nonOrderedPostProcessorNames.add(ppName);
         }
      }
      //调用实现了 PriorityOrdered 接口的 BeanFactoryPostProcessor
      sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
      // 执行 bean 工厂的后置处理
      invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

      //调用实现了 Ordered 接口的 BeanFactoryPostProcessor
      List orderedPostProcessors = new ArrayList<>();
      for (String postProcessorName : orderedPostProcessorNames) {
         orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
      }
      sortPostProcessors(orderedPostProcessors, beanFactory);
      // 执行 bean 工厂的后置处理
      invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

      //调用没有实现任何方法接口的
      List nonOrderedPostProcessors = new ArrayList<>();
      for (String postProcessorName : nonOrderedPostProcessorNames) {
         nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
      }
      // 执行 bean 工厂的后置处理
      invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
//-----------------------------------------处理BeanFactoryPostProcessor --End-----------------------------------------------------------------------------------------------------------------------------

      // Clear cached merged bean definitions since the post-processors might have
      // modified the original metadata, e.g. replacing placeholders in values...
      beanFactory.clearMetadataCache();

//------------------------- BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor调用完毕 --End-----------------------------------------------------------------------------------------------------------------------------

   }

首先判断beanFactory是不是BeanDefinitionRegistry的实例,当然肯定是的,然后执行如下操作:
1.定义了一个Set,装载BeanName,后面会根据这个Set,来判断后置处理器是否被执行过了。
2.定义了两个List,一个是regularPostProcessors,用来装载BeanFactoryPostProcessor,一个是registryProcessors用来装载BeanDefinitionRegistryPostProcessor,其中BeanDefinitionRegistryPostProcessor扩展了BeanFactoryPostProcessor。BeanDefinitionRegistryPostProcessor有两个方法,一个是独有的postProcessBeanDefinitionRegistry方法,一个是父类的postProcessBeanFactory方法。
3.循环传进来的beanFactoryPostProcessors,上面已经解释过了,一般情况下,这里永远都是空的,只有手动add beanFactoryPostProcessor,这里才会有数据。我们假设beanFactoryPostProcessors有数据,进入循环,判断postProcessor是不是BeanDefinitionRegistryPostProcessor,因为BeanDefinitionRegistryPostProcessor扩展了BeanFactoryPostProcessor,所以这里先要判断是不是BeanDefinitionRegistryPostProcessor,是的话,执行postProcessBeanDefinitionRegistry方法,然后把对象装到registryProcessors里面去,不是的话,就装到regularPostProcessors。
4.定义了一个临时变量:currentRegistryProcessors,用来装载BeanDefinitionRegistryPostProcessor。
5.getBeanNamesForType,顾名思义,是根据类型查到BeanNames,这里有一点需要注意,就是去哪里找,点开这个方法的话,就知道是循环beanDefinitionNames去找,这个方法以后也会经常看到。这里传了BeanDefinitionRegistryPostProcessor.class,就是找到类型为BeanDefinitionRegistryPostProcessor的后置处理器,并且赋值给postProcessorNames。一般情况下,只会找到一个,就是org.springframework.context.annotation.internalConfigurationAnnotationProcessor,也就是ConfigurationAnnotationProcessor。这个后置处理器在上一节中已经说明过了,十分重要。这里有一个问题,为什么我自己写了个类,实现了BeanDefinitionRegistryPostProcessor接口,也打上了@Component注解,但是这里没有获得,因为直到这一步,Spring还没有完成扫描,扫描是在ConfigurationClassPostProcessor类中完成的,也就是下面第一个invokeBeanDefinitionRegistryPostProcessors方法。
6.循环postProcessorNames,其实也就是org.springframework.context.annotation.internalConfigurationAnnotationProcessor,判断此后置处理器是否实现了PriorityOrdered接口(ConfigurationAnnotationProcessor也实现了PriorityOrdered接口),
如果实现了,把它添加到currentRegistryProcessors这个临时变量中,再放入processedBeans,代表这个后置处理已经被处理过了。当然现在还没有处理,但是马上就要处理了。。。
7.进行排序,PriorityOrdered是一个排序接口,如果实现了它,就说明此后置处理器是有顺序的,所以需要排序。当然目前这里只有一个后置处理器,就是ConfigurationClassPostProcessor。
8.把currentRegistryProcessors合并到registryProcessors,为什么需要合并?因为一开始spring只会执行BeanDefinitionRegistryPostProcessor独有的方法,而不会执行BeanDefinitionRegistryPostProcessor父类的方法,即BeanFactoryProcessor接口中的方法,所以需要把这些后置处理器放入一个集合中,后续统一执行BeanFactoryProcessor接口中的方法。当然目前这里只有一个后置处理器,就是ConfigurationClassPostProcessor。
9.可以理解为执行currentRegistryProcessors中的ConfigurationClassPostProcessor中的postProcessBeanDefinitionRegistry方法,这就是Spring设计思想的体现了,在这里体现的就是其中的热插拔,插件化开发的思想。Spring中很多东西都是交给插件去处理的,这个后置处理器就相当于一个插件,如果不想用了,直接不添加就是了。这个方法特别重要,我们后面会详细说来。
10.清空currentRegistryProcessors,因为currentRegistryProcessors是一个临时变量,已经完成了目前的使命,所以需要清空,当然后面还会用到。
11.再次根据BeanDefinitionRegistryPostProcessor获得BeanName,然后进行循环,看这个后置处理器是否被执行过了,如果没有被执行过,也实现了Ordered接口的话,把此后置处理器推送到currentRegistryProcessors和processedBeans中。
这里就可以获得我们定义的,并且打上@Component注解的后置处理器了,因为Spring已经完成了扫描,但是这里需要注意的是,由于ConfigurationClassPostProcessor在上面已经被执行过了,所以虽然可以通过getBeanNamesForType获得,但是并不会加入到currentRegistryProcessors和processedBeans。
12.处理排序。
13.合并Processors,合并的理由和上面是一样的。
14.执行我们自定义的BeanDefinitionRegistryPostProcessor。
15.清空临时变量。
16.在上面的方法中,仅仅是执行了实现了Ordered接口的BeanDefinitionRegistryPostProcessor,这里是执行没有实现Ordered接口的BeanDefinitionRegistryPostProcessor。
17.上面的代码是执行子类独有的方法,这里需要再把父类的方法也执行一次。
18.执行regularPostProcessors中的后置处理器的方法,需要注意的是,在一般情况下,regularPostProcessors是不会有数据的,只有在外面手动添加BeanFactoryPostProcessor,才会有数据。
19.查找实现了BeanFactoryPostProcessor的后置处理器,并且执行后置处理器中的方法。和上面的逻辑差不多,不再详细说明。
这就是这个方法中做的主要的事情了,可以说是比较复杂的。

我们来看看invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);这行代码
跟入进去,可以看到它是实现了多个方法,我们主要看的是ConfigurationClassPostProcessor

我们的重点是看到最后一行processConfigBeanDefinitions()方法,解析我们的bean定义,跟入进去

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
   int registryId = System.identityHashCode(registry);
   if (this.registriesPostProcessed.contains(registryId)) {
      throw new IllegalStateException(
            "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
   }
   if (this.factoriesPostProcessed.contains(registryId)) {
      throw new IllegalStateException(
            "postProcessBeanFactory already called on this post-processor against " + registry);
   }
   this.registriesPostProcessed.add(registryId);

   //真正的解析我们的bean定义
   processConfigBeanDefinitions(registry);
}

进入解析Bean定义的方法

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
   List configCandidates = new ArrayList<>();
   //获取IOC 容器中目前所有bean定义的名称
   String[] candidateNames = registry.getBeanDefinitionNames();

   //循环我们的上一步获取的所有的bean定义信息
   for (String beanName : candidateNames) {
      //通过bean的名称来获取我们的bean定义对象
      BeanDefinition beanDef = registry.getBeanDefinition(beanName);
      //判断是否有没有解析过
      if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
         if (logger.isDebugEnabled()) {
            logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
         }
      }
      //进行正在的解析判断是不是完全的配置类 还是一个非正式的配置类
      else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
         //满足添加 就加入到候选的配置类集合中
         configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
      }
   }

   // 若没有找到配置类 直接返回
   if (configCandidates.isEmpty()) {
      return;
   }

   //对我们的配置类进行Order排序
   configCandidates.sort((bd1, bd2) -> {
      int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
      int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
      return Integer.compare(i1, i2);
   });

   // 创建我们通过@CompentScan导入进来的bean name的生成器
   // 创建我们通过@Import导入进来的bean的名称
   SingletonBeanRegistry sbr = null;
   if (registry instanceof SingletonBeanRegistry) {
      sbr = (SingletonBeanRegistry) registry;
      if (!this.localBeanNameGeneratorSet) {
         BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
         if (generator != null) {
            //设置@CompentScan导入进来的bean的名称生成器(默认类首字母小写)也可以自己定义,一般不会
            this.componentScanBeanNameGenerator = generator;
            //设置@Import导入进来的bean的名称生成器(默认类首字母小写)也可以自己定义,一般不会
            this.importBeanNameGenerator = generator;
         }
      }
   }

   if (this.environment == null) {
      this.environment = new StandardEnvironment();
   }

   //创建一个配置类解析器对象
   ConfigurationClassParser parser = new ConfigurationClassParser(
         this.metadataReaderFactory, this.problemReporter, this.environment,
         this.resourceLoader, this.componentScanBeanNameGenerator, registry);

   //用于保存我们的配置类BeanDefinitionHolder放入上面筛选出来的配置类
   Set candidates = new LinkedHashSet<>(configCandidates);
   //用于保存我们的已经解析的配置类,长度默认为解析出来默认的配置类的集合长度
   Set alreadyParsed = new HashSet<>(configCandidates.size());
   //do while 会进行第一次解析
   do {
      //真正的解析我们的配置类
      parser.parse(candidates);
      parser.validate();

      //解析出来的配置类
      Set configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
      configClasses.removeAll(alreadyParsed);

      // Read the model and create bean definitions based on its content
      if (this.reader == null) {
         this.reader = new ConfigurationClassBeanDefinitionReader(
               registry, this.sourceExtractor, this.resourceLoader, this.environment,
               this.importBeanNameGenerator, parser.getImportRegistry());
      }
      // 此处才把@Bean的方法和@Import 注册到BeanDefinitionMap中
      this.reader.loadBeanDefinitions(configClasses);
      //加入到已经解析的集合中
      alreadyParsed.addAll(configClasses);

      candidates.clear();
      //判断我们ioc容器中的是不是>候选原始的bean定义的个数
      if (registry.getBeanDefinitionCount() > candidateNames.length) {
         //获取所有的bean定义
         String[] newCandidateNames = registry.getBeanDefinitionNames();
         //原始的老的候选的bean定义
         Set oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
         Set alreadyParsedClasses = new HashSet<>();
         //赋值已经解析的
         for (ConfigurationClass configurationClass : alreadyParsed) {
            alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
         }

         for (String candidateName : newCandidateNames) {
            //表示当前循环的还没有被解析过
            if (!oldCandidateNames.contains(candidateName)) {
               BeanDefinition bd = registry.getBeanDefinition(candidateName);
               //判断有没有被解析过
               if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
                     !alreadyParsedClasses.contains(bd.getBeanClassName())) {
                  candidates.add(new BeanDefinitionHolder(bd, candidateName));
               }
            }
         }
         candidateNames = newCandidateNames;
      }
   }
   //存在没有解析过的 需要循环解析
   while (!candidates.isEmpty());

   // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
   if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
      sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
   }

   if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
      // Clear cache in externally provided MetadataReaderFactory; this is a no-op
      // for a shared cache since it'll be cleared by the ApplicationContext.
      ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
   }
}

1.获得所有的BeanName,放入candidateNames数组。
2.循环candidateNames数组,根据beanName获得BeanDefinition,判断此BeanDefinition是否已经被处理过了。
3.判断是否是配置类,如果是的话。加入到configCandidates数组,在判断的时候,还会标记配置类属于Full配置类,还是Lite配置类,这里会引发一连串的知识盲点:
3.1 当我们注册配置类的时候,可以不加@Configuration注解,直接使用@Component @ComponentScan @Import @ImportResource等注解,Spring把这种配置类称之为Lite配置类, 如果加了@Configuration注解,就称之为Full配置类。
3.2 如果我们注册了Lite配置类,我们getBean这个配置类,会发现它就是原本的那个配置类,如果我们注册了Full配置类,我们getBean这个配置类,会发现它已经不是原本那个配置类了,而是已经被cgilb代理的类了。
3.3 写一个A类,其中有一个构造方法,打印出“你好”,再写一个配置类,里面有两个被@bean注解的方法,其中一个方法new了A类,并且返回A的对象,把此方法称之为getA,第二个方法又调用了getA方法,如果配置类是Lite配置类,会发现打印了两次“你好”,也就是说A类被new了两次,如果配置类是Full配置类,会发现只打印了一次“你好”,也就是说A类只被new了一次,因为这个类被cgilb代理了,方法已经被改写。
4.如果没有配置类直接返回。
5.处理排序。
6.解析配置类,可能是Full配置类,也有可能是Lite配置类,这个小方法是此方法的核心,稍后具体说明。
7.在第6步的时候,只是注册了部分Bean,像 @Import @Bean等,是没有被注册的,这里统一对这些进行注册。

下面是解析配置类的过程

public void parse(Set configCandidates) {

   //循环传进来的配置类
   for (BeanDefinitionHolder holder : configCandidates) {
      //获得BeanDefinition
      BeanDefinition bd = holder.getBeanDefinition();
      try {
         //如果获得BeanDefinition是AnnotatedBeanDefinition的实例
         if (bd instanceof AnnotatedBeanDefinition) {
            parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
         }
         else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
            parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
         }
         else {
            parse(bd.getBeanClassName(), holder.getBeanName());
         }
      }
      catch (BeanDefinitionStoreException ex) {
         throw ex;
      }
      catch (Throwable ex) {
         throw new BeanDefinitionStoreException(
               "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
      }
   }

   this.deferredImportSelectorHandler.process();
}

6.6 registerBeanPostProcessors()

实例化和注册beanFactory中扩展了BeanPostProcessor的bean。
例如:
AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)
RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)
CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。

public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

   //去容器中获取所有的BeanPostProcessor 的名称(还是bean定义)
   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

   /**
    * bean的后置处理器的个数 beanFactory.getBeanPostProcessorCount()成品的个数 之前refresh-->prepareBeanFactory()中注册的
    * postProcessorNames.length  beanFactory工厂中bean定义的个数
    * +1 在后面又马上注册了BeanPostProcessorChecker的后置处理器
    */
   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

   /**
    * 按照BeanPostProcessor实现的优先级接口来分离我们的后置处理器
    */
   //保存实现了priorityOrdered接口的
   List priorityOrderedPostProcessors = new ArrayList<>();
   //系统内部的
   List internalPostProcessors = new ArrayList<>();
   //实现了我们ordered接口的
   List orderedPostProcessorNames = new ArrayList<>();
   //没有优先级的
   List nonOrderedPostProcessorNames = new ArrayList<>();
   //循环我们的bean定义(BeanPostProcessor)
   for (String ppName : postProcessorNames) {
      //若实现了PriorityOrdered接口的
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         //显示的调用getBean流程创建bean的后置处理器
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
         //加入到集合中
         priorityOrderedPostProcessors.add(pp);
         //判断是否实现了MergedBeanDefinitionPostProcessor
         if (pp instanceof MergedBeanDefinitionPostProcessor) {
            //加入到集合中
            internalPostProcessors.add(pp);
         }
      }
      //判断是否实现了Ordered
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      //没有任何拍下接口的
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // 把实现了priorityOrdered注册到容器中
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   // 处理实现Ordered的bean定义
   List orderedPostProcessors = new ArrayList<>();
   for (String ppName : orderedPostProcessorNames) {
      //显示调用getBean方法
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      //加入到集合中
      orderedPostProcessors.add(pp);
      //判断是否实现了MergedBeanDefinitionPostProcessor
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         //加入到集合中
         internalPostProcessors.add(pp);
      }
   }
   //排序并且注册我们实现了Order接口的后置处理器
   sortPostProcessors(orderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);

   // 实例化我们所有的非排序接口的
   List nonOrderedPostProcessors = new ArrayList<>();
   for (String ppName : nonOrderedPostProcessorNames) {
      //显示调用
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);
      //判断是否实现了MergedBeanDefinitionPostProcessor
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   //注册我们普通的没有实现任何排序接口的
   registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

   //注册.MergedBeanDefinitionPostProcessor类型的后置处理器 bean 合并后的处理, Autowired 注解正是通过此方法实现诸如类型的预解析。
   sortPostProcessors(internalPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, internalPostProcessors);

   //注册ApplicationListenerDetector 应用监听器探测器的后置处理器
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

6.7 initMessageSource()

初始化国际化资源处理器 (不是主线代码,没啥学习价值,可以直接忽略)

protected void initMessageSource() {
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   //先判断容器中有没对应的bean
   if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
      this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
      // Make MessageSource aware of parent MessageSource.
      if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
         HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
         if (hms.getParentMessageSource() == null) {
            // Only set parent context as parent MessageSource if no parent MessageSource
            // registered already.
            //设置父容器的MessageSource
            hms.setParentMessageSource(getInternalParentMessageSource());
         }
      }
      if (logger.isTraceEnabled()) {
         logger.trace("Using MessageSource [" + this.messageSource + "]");
      }
   } else {
      //容器中不存在,就新创建一个,然再将其放到ioc中
      DelegatingMessageSource dms = new DelegatingMessageSource();
      dms.setParentMessageSource(getInternalParentMessageSource());
      this.messageSource = dms;
      beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
      if (logger.isTraceEnabled()) {
         logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
      }
   }
}

6.8 initApplicationEventMulticaster()

初始化事件派发器,该对象存有一个list,值的内容是监听器,里面还有个发布事件的方法,发布事件时,遍历监听器,调用每个监听器去处理该事件

protected void initApplicationEventMulticaster() {
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   //容器中已存在就直接获取
   if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
      this.applicationEventMulticaster =
            beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
      if (logger.isTraceEnabled()) {
         logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
      }
   } else {
      //容器中不存在就创建
      this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
      beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
      if (logger.isTraceEnabled()) {
         logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
               "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
      }
   }
}

6.9 onRefresh()

这个方法同样也是留个子类实现的springboot也是从这个方法进行启动tomcat的,且它是一个模板方法,在容器刷新的时候可以自定义逻辑,不同的Spring容器做不同的事情

protected void onRefresh() throws BeansException {
   // For subclasses: do nothing by default.
}

6.10 registerListeners()

把我们的事件监听器注册到多播器上,然后派发事件

protected void registerListeners() {
   // 容器中已存在就直接获取
   for (ApplicationListener listener : getApplicationListeners()) {
      getApplicationEventMulticaster().addApplicationListener(listener);
   }

   // Do not initialize FactoryBeans here: We need to leave all regular beans
   // uninitialized to let post-processors apply to them!
   String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
   for (String listenerBeanName : listenerBeanNames) {
      getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
   }

   // 容器中不存在就创建
   Set earlyEventsToProcess = this.earlyApplicationEvents;
   this.earlyApplicationEvents = null;
   if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
      for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
         getApplicationEventMulticaster().multicastEvent(earlyEvent);
      }
   }
}

6.11 finishBeanFactoryInitialization()

实例化剩余的单实例Bean (循环所有的Bean定义,将Bean注册到IOC容器中) 底层实现了getBean方法,实例化Bean对象

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // 为我们的bean工厂创建类型转化器  Convert
   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));
   }

   // Register a default embedded value resolver if no bean post-processor
   // (such as a PropertyPlaceholderConfigurer bean) registered any before:
   // at this point, primarily for resolution in annotation attribute values.
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   // 处理关于aspectj
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {

      //getBean方法,就相当于实例化Bean对象了
      getBean(weaverAwareName);
   }

   // Stop using the temporary ClassLoader for type matching.
   beanFactory.setTempClassLoader(null);

   //允许缓存所有bean定义元数据,而不期望进一步的更改
   //冻结所有的Bean定义,说明注册的Bean定义将不被修改或任何进一步处理(可以理解为:Spring要进行生产Bean了,所以不允许外部再进行修改Bean)
   beanFactory.freezeConfiguration();

   //实例化剩余的单实例bean(这里指的剩余的Bean是被invokeBeanFactoryPostProcessors方法解析的@conponent注解的类嘛,直接解析成Bean定义了
   // 但是还没有实例化,而那些创世纪的类,已经在invokeBeanFactoryPostProcessors方法实例化完成了)
   beanFactory.preInstantiateSingletons();
}

在这个方法我们主要看两个步骤
1.beanFactory.freezeConfiguration(); 冻结所有的Bean定义
2.beanFactory.preInstantiateSingletons(); 开始实例化剩余的Bean

我们进入finishBeanFactoryInitialization这方法,里面有一个beanFactory.freezeConfiguration()方法
我们进入方法中,其实就是只做了一件事情,就是将所有的Bean都设置为true,这样IOC容器在继续实例化Bean的时候,只要判断Bean是否为true即可
可能为有疑惑,为什么要冻结 因为 我们在实例化Bean(生产Bean)的过程中, 外部又需要进行修改Bean 所以就会进行判断该Bean的属性是否为true,如果为true说明在生产Bean,还不能够对Bean进行修改,只有等false了,才能继续修改哦

@Override
public void freezeConfiguration() {
   this.configurationFrozen = true;
   this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}

好,第一个步骤看完后,我们在接下来再来跟第二个步骤
我们再进入finishBeanFactoryInitialization这方法,里面有一个beanFactory.preInstantiateSingletons()方法,也就是该方法的最后一行代码

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

   // Iterate over a copy to allow for init methods which in turn register new bean definitions.
   // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
   //获取我们容器中所有bean定义的名称
   List beanNames = new ArrayList<>(this.beanDefinitionNames);

   // Trigger initialization of all non-lazy singleton beans...
   //循环我们所有的bean定义名称
   for (String beanName : beanNames) {
      //合并我们的bean定义,转换为统一的RootBeanDefinition类型(在), 方便后续处理
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

      /**
       * 根据bean定义判断是不是抽象的&& 不是单例的 &&不是懒加载的
       */
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {

         //是否为工厂Bean
         if (isFactoryBean(beanName)) {
            // 是factoryBean会先生成实际的bean  &beanName 是用来获取实际bean的
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
               FactoryBean factory = (FactoryBean) bean;
               boolean isEagerInit;
               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                  isEagerInit = AccessController.doPrivileged(
                        (PrivilegedAction) ((SmartFactoryBean) factory)::isEagerInit,
                        getAccessControlContext());
               } else {
                  isEagerInit = (factory instanceof SmartFactoryBean &&
                        ((SmartFactoryBean) factory).isEagerInit());
               }
               //调用真正的getBean的流程
               if (isEagerInit) {
                  getBean(beanName);
               }
            }
         } else {
            //非工厂Bean,就是普通的Bean对象
            getBean(beanName);
         }
      }
   }

   //或有的bean的名称 ...........到这里所有的单实例的bean已经记载到单实例bean到缓存中
   for (String beanName : beanNames) {
      //从单例缓存池中获取所有的对象
      Object singletonInstance = getSingleton(beanName);
      //判断当前的bean是否实现了SmartInitializingSingleton接口
      if (singletonInstance instanceof SmartInitializingSingleton) {
         SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction) () -> {
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         } else {
            //触发实例化之后的方法afterSingletonsInstantiated
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
}

首先会将beanDefinitionMap里面的所有的Bean的名称放在一个集合中,然后遍历集合里的Bean的名称
为什么是遍历Bean的名称,而不是遍历Bean实例呢?
是因为不同的注解注入的Bean是不统一的,例如@Component 和 @Bean 两种方法注册的Bean格式是不一样的,所以才会需要根据Bean的名称去遍历

然后我们在看到if判断 isFactoryBean(beanName) 的这个,判断它是否为工厂Bean,注意这里判断的工厂Bean

@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
   String beanName = transformedBeanName(name);
   Object beanInstance = getSingleton(beanName, false);
   if (beanInstance != null) {
      return (beanInstance instanceof FactoryBean);
   }
   // No singleton instance found -> check bean definition.
   if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
      // No bean definition found in this factory -> delegate to parent.
      return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
   }
   return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}

是判断该Bean是否实现了FactoryBean,如果没有实现则进入,调用我们的getBean进行真正的实例化Bean操作
如果是工厂Bean则进行特殊处理,然后进行实例化Bean操作

Spring5.0源码深度解析之Spring IOC加载_第8张图片

我们这里是没有实现的
所以进入普通Bean实例化,也就是进入方法,开始调用getBean()方法来进行实例化对象


Spring5.0源码深度解析之Spring IOC加载_第9张图片

我们跟进getBean底层方法,doGetBean()方法

@Override
public Object getBean(String name) throws BeansException {
   return doGetBean(name, null, null, false);
}

在跟进去

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

   /**
    * 在这里 传入进来的name 可能是别名, 也有可能是工厂bean的name,所以在这里需要转换,获取最真实的Bean名称
    */
   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 + "'");
         }
      }
      /**
       * /*
       *
       * 如果 sharedInstance 是普通的单例 bean,下面的方法会直接返回。但如果
       * sharedInstance 是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的
       * bean 实例。如果用户想获取 FactoryBean 本身,这里也不会做特别的处理,直接返回
       * 即可。毕竟 FactoryBean 的实现类本身也是一种 bean,只不过具有一点特殊的功能而已。
       */
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
   }

   else {
      /**
       * spring 只能解决单例对象的setter 注入的循环依赖,不能解决构造器注入
       */
      if (isPrototypeCurrentlyInCreation(beanName)) {
         throw new BeanCurrentlyInCreationException(beanName);
      }

      /**
       * 判断AbstractBeanFacotry工厂是否有父工厂(一般情况下是没有父工厂因为abstractBeanFactory直接是抽象类,不存在父工厂)
       * 一般情况下,只有Spring 和SpringMvc整合的时才会有父子容器的概念,
       * 比如我们的Controller中注入Service的时候,发现我们依赖的是一个引用对象,那么他就会调用getBean去把service找出来
       * 但是当前所在的容器是web子容器,那么就会在这里的 先去父容器找
       */
      BeanFactory parentBeanFactory = getParentBeanFactory();
      //若存在父工厂,切当前的bean工厂不存在当前的bean定义,那么bean定义是存在于父beanFacotry中
      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
         //获取bean的原始名称
         String nameToLookup = originalBeanName(name);
         //若为 AbstractBeanFactory 类型,委托父类处理
         if (parentBeanFactory instanceof AbstractBeanFactory) {
            return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                  nameToLookup, requiredType, args, typeCheckOnly);
         }
         else if (args != null) {
            //  委托给构造函数 getBean() 处理
            return (T) parentBeanFactory.getBean(nameToLookup, args);
         }
         else if (requiredType != null) {
            return parentBeanFactory.getBean(nameToLookup, requiredType);
         }
         else {
            // 没有 args,委托给标准的 getBean() 处理
            return (T) parentBeanFactory.getBean(nameToLookup);
         }
      }

      /**
       * 方法参数 typeCheckOnly ,是用来判断调用 #getBean(...) 方法时,表示是否为仅仅进行类型检查获取 Bean 对象
       * 如果不是仅仅做类型检查,而是创建 Bean 对象,则需要调用 #markBeanAsCreated(String beanName) 方法,进行记录
       */
      if (!typeCheckOnly) {
         markBeanAsCreated(beanName);
      }

      try {
         /**
          * 从容器中获取 beanName 相应的 GenericBeanDefinition 对象,并将其转换为 RootBeanDefinition 对象
          *   
          
          
          
          */
         RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         //检查当前创建的bean定义是不是抽象的bean定义
         checkMergedBeanDefinition(mbd, beanName, args);

         /**
          *
          * @Bean
         public DependsA dependsA() {
         return new DependsA();
         }

          @Bean
          @DependsOn(value = {"dependsA"})
          public DependsB dependsB() {
          return new DependsB();
          }
           * 处理dependsOn的依赖(这个不是我们所谓的循环依赖 而是bean创建前后的依赖)
          */
         //依赖bean的名称
         String[] dependsOn = mbd.getDependsOn();
         if (dependsOn != null) {
            // <1> 若给定的依赖 bean 已经注册为依赖给定的 bean
            // 即循环依赖的情况,抛出 BeanCreationException 异常
            for (String dep : dependsOn) {
               //beanName是当前正在创建的bean,dep是正在创建的bean的依赖的bean的名称
               if (isDependent(beanName, dep)) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
               }
               //保存的是依赖 beanName 之间的映射关系:依赖 beanName - > beanName 的集合
               registerDependentBean(dep, beanName);
               try {
                  //获取depentceOn的bean
                  getBean(dep);
               } catch (NoSuchBeanDefinitionException ex) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
               }
            }
         }

         //创建单例bean
         if (mbd.isSingleton()) {
            //把beanName 和一个singletonFactory 并且传入一个回调对象用于回调
            sharedInstance = getSingleton(beanName, () -> {
               try {
                  //进入创建bean的逻辑
                  return createBean(beanName, mbd, args);
               } catch (BeansException ex) {
                  //创建bean的过程中发生异常,需要销毁关于当前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();
            if (!StringUtils.hasLength(scopeName)) {
               throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
            }
            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;
}

看到这么多代码,莫慌,我们只看重点。
我们看到这里面的createBean方法,再点进去啊,但是又点不进去了,这是接口啊,但是别慌,这个接口又只有一个实现类,所以说 没事,就是干,这个实现类为org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory。
这个实现的方法里面又做了很多事情,我们就不去看了,我就是带着大家找到那几个生命周期的回调到底定义在哪里就OK了。

if (mbd.isSingleton()) {

                    //getSingleton中的第二个参数类型是ObjectFactory,是一个函数式接口,不会立刻执行,而是在
                    //getSingleton方法中,调用ObjectFactory的getObject,才会执行createBean
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

跟进去createBean方法

@Override
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 已经被解析了
   Class resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }

   // Prepare method overrides.
   try {
      /**
       * 验证和准备覆盖方法( 仅在XML方式中)
       * lookup-method 和 replace-method
       * 这两个配置存放在 BeanDefinition 中的 methodOverrides( 仅在XML方式中)
       * 在XML方式中 bean 实例化的过程中如果检测到存在 methodOverrides ,
       * 则会动态地位为当前 bean 生成代理并使用对应的拦截器为 bean 做增强处理。
       * 具体的实现我们后续分析,现在先看 mbdToUse.prepareMethodOverrides() 代码块
       */
      mbdToUse.prepareMethodOverrides();
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }

   try {
      /**
       * 第1个bean后置处理器
       * 通过bean的后置处理器来进行后置处理生成代理对象,一般情况下在此处不会生成代理对象
       * 为什么不能生成代理对象,不管是我们的jdk代理还是cglib代理都不会在此处进行代理,因为我们的
       * 真实的对象没有生成,所以在这里不会生成代理对象,那么在这一步是我们aop和事务的关键,因为在这里
       * 解析我们的aop切面信息进行缓存
       */
      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) {
      // A previously detected exception with proper bean creation context already,
      // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
   }
}

莫慌,我们关注重点,看如下代码

   Object beanInstance = doCreateBean(beanName, mbdToUse, args);//创建bean,核心
            if (logger.isDebugEnabled()) {
                logger.debug("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;

再继续深入doCreateBean方法,这个方法又做了一堆一堆的事情,但是值得开心的事情就是 我们已经找到了我们要寻找的东西了。

创建实例
首先是创建实例,位于:

instanceWrapper = createBeanInstance(beanName, mbd, args);//创建bean的实例。核心

填充属性
其次是填充属性,位于:

populateBean(beanName, mbd, instanceWrapper);//填充属性,炒鸡重要

继续深入进去。
aware系列接口的回调
aware系列接口的回调位于initializeBean中的invokeAwareMethods方法:

invokeAwareMethods(beanName, bean);
private void invokeAwareMethods(final String beanName, final Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof BeanNameAware) {
                ((BeanNameAware) bean).setBeanName(beanName);
            }
            if (bean instanceof BeanClassLoaderAware) {
                ClassLoader bcl = getBeanClassLoader();
                if (bcl != null) {
                    ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
                }
            }
            if (bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
            }
        }
    }

BeanPostProcessor的postProcessBeforeInitialization方法
BeanPostProcessor的postProcessBeforeInitialization方法位于initializeBean的

if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }
    @Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessBeforeInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

afterPropertiesSet init-method
afterPropertiesSet init-method位于initializeBean中的

 invokeInitMethods(beanName, wrappedBean, mbd);

这里面调用了两个方法,一个是afterPropertiesSet方法,一个是init-method方法:

    ((InitializingBean) bean).afterPropertiesSet();
invokeCustomInitMethod(beanName, bean, mbd);

BeanPostProcessor的postProcessAfterInitialization方法
BeanPostProcessor的postProcessAfterInitialization方法位于initializeBean的

if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessAfterI nitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

当然在实际的开发中,应该没人会去销毁Spring的应用上下文把,所以剩余的两个销毁的回调就不去找了。

6.12 finishRefresh()

最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的)

protected void finishRefresh() {

   //1.清除缓存
   clearResourceCaches();

   //2.为此上下文初始化生命周期处理器
   initLifecycleProcessor();

   //3.首先将刷新完毕事件传播到生命周期处理器(触发isAutoStartup方法返回true的SmartLifecycle的start方法)
   getLifecycleProcessor().onRefresh();

   // 4.推送上下文刷新完毕事件到相应的监听器
   publishEvent(new ContextRefreshedEvent(this));

   // 5.这个方法不清楚啥作用
   LiveBeansView.registerApplicationContext(this);
}

到此本文的Spring IOC 加载流程源码分析完毕。

你可能感兴趣的:(Spring5.0源码深度解析之Spring IOC加载)