spring源码解析:spring的启动过程


前言

现在基本上所有的Java项目都会用spring,那么在项目启动的过程中是如何启动spring的?spring的入口有很多,有的使用xml,有的使用注解,但总归都是ApplicationContext的实现类,通过创建ApplicationContext的对象来启动spring。

从demo看启动过程

通过注解配置的方式,来看看spring是如何启动的

public class Main {
    public static void main(String[] args) {
    //ZTest1Config.class注解配置类
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ZTest1Config.class);
    }
}

可以看到启动spring只需一行代码,创建一个对象,那么创建这个对象时做了哪些事?

    /**
     * 1.创建一个新的容器,初始化容器的相关资源,为后续使用。初始化两大成员: AnnotatedBeanDefinitionReader ,ClassPathBeanDefinitionScanner
     * 2.注册配置类
     * 3.刷新容器
     * @param componentClasses 注解配置类,可以有多个
     */
    public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
        this();
        register(componentClasses);
        refresh();
    }

创建AnnotationConfigApplicationContext对象时,做了以上三件事,对应以上三个方法(前两个方法是在准备环境,核心在第三个),在进一步探索这三个方法是如何实现的

调用无参构造

首先它会调用自己的无参构造,初始化必要的成员。

    /*
    * 这里创建spring容器的两大成员
    *     1.注解的bean定义读取器:
    *         a.创建ConditionEvaluator,主要记录了容器的重要信息
    *         b.给bean工厂注册各种后置处理器。
    *     2.类路劲的bean定义扫描器:
    *         a.注册了扫描过滤器。哪些注解的bean是需要被扫描的
    *         b.内部创建了一个元数据缓存工厂,为了后面初始化bean存储类以及类的文件信息
    *
    * */
    public AnnotationConfigApplicationContext() {
        StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
        this.reader = new AnnotatedBeanDefinitionReader(this);
        createAnnotatedBeanDefReader.end();
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

上面创建了AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner。这两个类都是Spring中用来读取Bean定义信息的组件,但侧重点不同:
AnnotatedBeanDefinitionReader:主要用于将基于注解的 Bean 定义注册到 Spring 容器中。其主要作用包括:

  • 主要通过反射扫描指定的包路径下的类,并识别类上的注解(如 @Component@Service@Repository@Controller 等)。
  • 将扫描到的带有注解的类转化为 Spring 的 Bean 定义(BeanDefinition)。
  • 将这些 Bean 定义注册到 Spring 容器中,以便后续通过容器获取并管理这些 Bean。
  • 常用实现是AnnotationConfigApplicationContext中的AnnotatedBeanDefinitionReader。

ClassPathBeanDefinitionScanner:也用于扫描和注册基于注解的 Bean 定义,但它具有更灵活的配置选项,可以进行更高级的扫描和筛选。其主要作用包括

  • 扫描指定包路径下的类,并可以配置扫描过滤器,以筛选出符合特定条件的类。
  • 在扫描过程中调用自定义的Bean定义注册器进行注册。
  • 默认会扫描@Component等注解,但可自定扫描逻辑。
  • 常用实现类是ClassPathBeanDefinitionScanner。

创建AnnotatedBeanDefinitionReader

这里会调用AnnotatedBeanDefinitionReader的有参构造 传入两个参数:BeanDefinitionRegistry,Environment

  • BeanDefinitionRegistry-实例为容器本身,即AnnotationConfigApplicationContext
  • Environment-实例是StandardEnvironment
/**
*    这里的两个参数一个是容器本身(AnnotationConfigApplicationContext实现了BeanDefinitionRegistry)
*   一个是容器环境-通过代码调用链查看,最后会创建一个 new StandardEnvironment() 
*/
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
    this(registry, getOrCreateEnvironment(registry));
}

private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    if (registry instanceof EnvironmentCapable) {
        return ((EnvironmentCapable) registry).getEnvironment();
    }
    return new StandardEnvironment();
}

    public ConfigurableEnvironment getEnvironment() {
    if (this.environment == null) {
        this.environment = createEnvironment();
    }
    return this.environment;
}

protected ConfigurableEnvironment createEnvironment() {
    return new StandardEnvironment();
}

有参构造做了三件事:

  • 记录bean定义注册器
  • 创建条件评估器conditionEvaluator。
  • 给bean工厂注册各种后置处理器。
/**
 * 创建AnnotatedBeanDefinitionReader 。
     * 1.赋值BeanDefinitionRegistry
     * 2.创建ConditionEvaluator,记录相关信息
     * 3.注册bean的后置处理器
 * @param registry  实现类 AnnotationConfigApplicationContext
 * @param environment  实现类 StandardEnvironment
 */
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    Assert.notNull(environment, "Environment must not be null");
    this.registry = registry;

    /*创建ConditionEvaluator,同时创建静态内部类对象ConditionContextImpl给context赋值(主要处理@Conditional注解的判断逻辑。@Conditional注解可以用来有条件地包含或排除配置类和bean的注册。如果指定的条件为true,则该类或bean会被注册,否则会被忽略)
    *
    * 主要作用记录了spring容器的重要信息为了后面使用:
    *     记录bean定义的注册器
    *     记录bean工厂是谁
    *     记录spring的环境
    *     记录当前的资源加载器
    *     记录类加载器
    * */
    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
    /*
    * 给bean工厂注册各种后置处理器。
    *    1.注册了依赖排序器
    *     2.注册Autowire候选处理器
    *     3.注册配置类后置处理器(spring的bean扫描,解析就是这个处理器完成的)
    *     4.注册@Autowire注解的后置处理器,处理@Autowire注解
    *     5.注册JSR规范的注解处理器 (@Resource,@PostConstruct,@PreDestroy等注解都是通过此处理器完成)
    *      6.注册jpa后置处理器
    *     7.注册监听方法的事件监听处理器(查找bean工厂中带有@EventListeners注解的bean的方法放入事件监听器的集合)
    *     8.注册事件监听器工厂
    * */
    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

上述代码中‘bean定义注册器’实际上就是容器本身,再来看看如何创建创建条件评估器conditionEvaluator以及怎么给给bean工厂注册各种后置处理器。

创建conditionEvaluator

/**
 * Create a new {@link ConditionEvaluator} instance.
 */
public ConditionEvaluator(@Nullable BeanDefinitionRegistry registry,
        @Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {

    this.context = new ConditionContextImpl(registry, environment, resourceLoader);
}

/**
* 创建ConditionContextImpl实例。(ConditionContextImpl是@Conditional注解的条件上下文实现类。用于提供条件判断时需要的环境信息)
* 1.设置BeanDefinitionRegistry 实例为AnnotationConfigApplicationContext
* 2.设置ConfigurableListableBeanFactory 实例为DefaultListableBeanFactory 在创建实例AnnotationConfigApplicationContext时 自动创建了实例为DefaultListableBeanFactory实现
* 3.设置Environment 实例为StandardEnvironment
* 4.设置ResourceLoader  实例为DefaultResourceLoader
* 5.设置classLoader 实例为 ClassLoader.getSystemClassLoader(); AppClassLoader
* @param registry 实例为AnnotationConfigApplicationContext
* @param environment 实例为StandardEnvironment
* @param resourceLoader null
*/
public ConditionContextImpl(@Nullable BeanDefinitionRegistry registry,
@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {

    this.registry = registry;
    this.beanFactory = deduceBeanFactory(registry);
    this.environment = (environment != null ? environment : deduceEnvironment(registry));
    this.resourceLoader = (resourceLoader != null ? resourceLoader : deduceResourceLoader(registry));
    this.classLoader = deduceClassLoader(resourceLoader, this.beanFactory);
}

给bean工程注册各种后置处理器-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);
}


/**
* 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
* 这个方法主要是根据当前的bean工厂做一些设置:
* 1.添加一个默认的比较器
* 2.设置一个上下文的筛选器(蛀牙对ban的查找进行筛选的类)
* 3.添加ConfigurationClassPostProcessor成一个BeanDefinition;
* 4.添加AutowiredAnnotationBeanPostProcessor成一个BeanDefinition;
* 5.添加CommonAnnotationBeanPostProcessor成一个BeanDefinition;
* 6.添加EventListenerMethodProcessor成一个BeanDefinition;
* 7.添加DefaultEventListenerFactory成一个BeanDefinition;
* 在没有启用JPA的情况下,胡添加5个BeanDefinition(后置处理器),一个比较器BeanDefinition,一个bean筛选器(BeanDefinition)
*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
     BeanDefinitionRegistry registry, @Nullable Object source) {

  //先得到一个工厂Bean工厂,这个Bean工厂是之前初始化好的,是一个DefaultListableBeanFactory
  DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
  if (beanFactory != null) {
     //这里的Bean工厂肯定不能为空,这里是设置比较器的,如果说你没有设置比较器之类的,这里设置一个默认的比较器,这个比较器
     //可以在使用BeanDefinition排序的时候使用,比如说你实现了Order接口或者PriorityOrdered的时候,BeanDefinition的执行
     //顺序可以使用它来进行排序
     if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
        beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
     }
     //这里就是之前我们看的bean中的依赖注入的时候,先byType的时候,对找到的多个bean有筛选,比如先byType,再进行是否启用了
     //自动注入候选者,泛型的判断以及Qualifier的筛选
     /**
      * ContextAnnotationAutowireCandidateResolver中的父类是QualifierAnnotationAutowireCandidateResolver
      * QualifierAnnotationAutowireCandidateResolver主要是对泛型的筛选和Qualifier的bean进行筛选,而ContextAnnotationAutowireCandidateResolver
      * 是QualifierAnnotationAutowireCandidateResolver它的子类,主要提供了一些代理工厂的创建,延迟加载的一些判断
      */
     if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
        beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
     }
  }

  Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

   //这里添加一个ConfigurationClass的后置处理器到bd中
  if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
     /**
      * 这里添加的是ConfigurationClassPostProcessor这个BeanDefinition,这个BeanDefinition很重要
      * 它本身也是一个beanFactory的后置处理器,这里添加进去的意思就是说后面spring启动扫描的时候就是用这个后置处理器来
      * 扫描我们的配置类,比如我的配置类是Appconfig,那么这个后置处理器就是专门处理这个配置类配置的类路径信息
      * 所以说这个beanFactory后置处理器非常重要,简单来说就是对我们配置类路径进行扫描,扫描成一个一个的BeanDefinition
      * 然后放入beanDefinitonMap中,就是这个ConfigurationClassPostProcessor后置处理器来做的事情
      *
      * 这里生成的是一个RootBeanDefinition,看了spring的生命周期都知道,spring中的扫描成的BeanDefinition最后都会合并成
      * RootBeanDefiniton,意思就是它没有父类的bd了
      */
     RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
     def.setSource(source);
     beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
  }
  //这里添加一个AutowiredAnnotationBeanPostProcessor,这个AutowiredAnnotationBeanPostProcessor在spring的生命周期中
  //非常重要,主要是处理依赖注入的@AutoWired
  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));
  }
  /**
   * 下面这个注册是CommonAnnotationBeanPostProcessor,这个bean的后置处理器主要处理@Resource、@PostConstruct
   * @PreDestory注解,也是依赖注入的一部分,这里先把这个bean的后置处理器加入到beanDefinitionMap中
   */
  // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
  if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
     RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
     def.setSource(source);
     beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
  }

  // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
  //如果你的系统中启用了JPA的方式,那么这里添加一个JPA的后置处理器
  if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
     RootBeanDefinition def = new RootBeanDefinition();
     try {
        def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
              AnnotationConfigUtils.class.getClassLoader()));
     }
     catch (ClassNotFoundException ex) {
        throw new IllegalStateException(
              "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
     }
     def.setSource(source);
     beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
  }

  //事件方法的监听器BeanFactoryPostProcessor,是一个bean工厂的后置处理器
  if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
     RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
     def.setSource(source);
     beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
  }
  //这里添加的是一个默认的事件监听工厂
  if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
     RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
     def.setSource(source);
     beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
  }

  return beanDefs;
}

到此spring容器的第一个重要的成员AnnotatedBeanDefinitionReader创建完毕。

  • 这里值得关注的一点,注册了ConfigurationClassPostProcessor处理器,在启动过程中这个类很重要。用于处理我们的配置类

创建ClassPathBeanDefinitionScanner

再来看看ClassPathBeanDefinitionScanner是如何创建的,再创建时做了哪些事?看如下调用链

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
    this(registry, true);
}

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
    this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
        Environment environment) {

    this(registry, useDefaultFilters, environment,
            (registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}


/**
 * 创建ClassPathBeanDefinitionScanner实例
 * 1. 给BeanDefinitionRegistry赋值
 * 2. 给父类的includeFilters 添加默认的注解过滤器 @Component
 * 3. 给父类的environment 赋值
 * 4. 为父类设置资源加载器,三个属性赋值
 *         ResourcePatternResolver的实例为AnnotationConfigApplicationContext 、
 *         创建metadataReaderFactory实例为缓存工厂,内部维护了一个map作为缓存(实例为concurrentMap)
 *         赋值componentsIndex 第一次暂时为null
 * @param registry AnnotationConfigApplicationContext
 * @param useDefaultFilters true
 * @param environment  StandardEnvironment
 * @param resourceLoader AnnotationConfigApplicationContext
 */
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
        Environment environment, @Nullable ResourceLoader resourceLoader) {

    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    /*记录bean定义的注册器*/
    this.registry = registry;

    /*注册三个过滤器,哪些注解要被扫描到:可以自动扫描和处理标注了Spring原生注解@Component以及Java EE注解@ManagedBean、@Named的类
    *     1.@Component注解,以及被@Component元注解标记的注解
    *     2.JavaEE6的@ManagedBean注解,如果有的话
    *     3.JSR-330的@Named注解,如果有的话
    * */
    if (useDefaultFilters) {
        registerDefaultFilters();
    }
    /*设置扫描环境*/
    setEnvironment(environment);
    /*
    * 设置解析相关资源的处理器
    *     这里最主要的就是创建了一个元数据的读取工厂。为后面初始化bean缓存了bean的类以及真是文件信息
    * */
    setResourceLoader(resourceLoader);
}

调用链最后最后的一个构造方法才是创建ClassPathBeanDefinitionScanner的逻辑。

看看setResourceLoader方法做了哪些事?

/*
* 1.设置资源模式解析器,实际上就是容器本身
* 2.创建一个元数据缓存读取工厂
* 3.componentsIndex=null
* */
@Override
public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {
    this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
    /*
    * 这里创建一个元数据读取工厂。
    *     1.记录了resourceLoader 实际上是容器本身
    *     2.记录MetadataReader并创建。,在defaultResourceLoader的resourceCaches中添加了一个MetadataReader为key,value为ConcurrentHashMap。将value作为MetadataReader
    * */
    this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);

    /*
    * 用于加载候选组件索引文件。这个类的主要目的是在 Spring 的组件扫描过程中提高性能,通过索引文件来快速定位候选组件
    * */
    this.componentsIndex = CandidateComponentsIndexLoader.loadIndex(this.resourcePatternResolver.getClassLoader());
}

@Nullable
public static CandidateComponentsIndex loadIndex(@Nullable ClassLoader classLoader) {
    ClassLoader classLoaderToUse = classLoader;
    if (classLoaderToUse == null) {
        classLoaderToUse = CandidateComponentsIndexLoader.class.getClassLoader();
    }
    return cache.computeIfAbsent(classLoaderToUse, new Function<ClassLoader, CandidateComponentsIndex>() {
        @Override
        public CandidateComponentsIndex apply(ClassLoader classLoader1) {
            return doLoadIndex(classLoader1);
        }
    });
}

/**
* 通过遍历所有jar包下的spring.components索引文件,汇总并封装为一个CandidateComponentsIndex对象,供后续组件扫描使用。
*/
@Nullable
private static CandidateComponentsIndex doLoadIndex(ClassLoader classLoader) {
    if (shouldIgnoreIndex) {
        return null;
    }

    try {
        Enumeration<URL> urls = classLoader.getResources(COMPONENTS_RESOURCE_LOCATION);
        if (!urls.hasMoreElements()) {
            return null;
        }
        List<Properties> result = new ArrayList<>();
        while (urls.hasMoreElements()) {
            URL url = urls.nextElement();
            Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
            result.add(properties);
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Loaded " + result.size() + " index(es)");
        }
        int totalCount = result.stream().mapToInt(Properties::size).sum();
        return (totalCount > 0 ? new CandidateComponentsIndex(result) : null);
    }
    catch (IOException ex) {
        throw new IllegalStateException("Unable to load indexes from location [" +
                COMPONENTS_RESOURCE_LOCATION + "]", ex);
    }
}

到此启动容器的第一步已经完成。在这一步中完成了

  1. 初始化Bean定义的读取器readers和扫描器scanners,用来加载配置类和带注解的类。
  2. 初始化环境environment的实现,读取环境变量等。
  3. 初始化事件处理器event multicaster。
  4. 初始化 SpecificAnnotationAttributeExtractor,用于提取注解的属性值。
  5. 初始化注解配置缓存annotatedClassesCache。
  6. 初始化容器的基础设施,如条件评估器conditionEvaluator等。
  7. 绑定配置中的占位符placeholderConfigurer支持。
    等等。

所以this()方法实现了注解驱动Spring容器的基础初始化工作,为后续的注解配置类解析和注解Bean定义注册做好了准备。

注册配置类

register()方法就是通过解析配置类,将其注册为Spring容器内部的Bean定义,为后续实例化Bean做准备。

register()方法的主要逻辑:

  1. 通过AnnotatedBeanDefinitionReader读取配置类信息,解析组件类上面的注解元数据,生成BeanDefinitionHolder对象。
  2. 将读取到的BeanDefinitionHolder注册到内部的beanDefinitionMap中,其中key为bean名称,value为BeanDefinition对象。
  3. 遍历组件类上的注解,提取相关的注解属性并设置到AnnotationConfigUtils.ATTRIBUTES_FROM_COMPONENT_CLASS属性中,保存到后续使用。
  4. 如果组件类实现了BeanNameGenerator接口,还会设置bean名称生成器。
  5. 如果组件类实现了ScopeMetadataResolver接口,还会设置作用域元数据解析器。
  6. 如果组件类实现了ImportAware接口,将处理import相关的配置。
  7. 最后将配置类Class对象保存到内部集合annotatedClasses中,方便后续处理。
public void register(Class<?>... componentClasses) {
    for (Class<?> componentClass : componentClasses) {
        registerBean(componentClass);
    }
}

public void register(Class<?>... componentClasses) {
    Assert.notEmpty(componentClasses, "At least one component class must be specified");
    StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
            .tag("classes", () -> Arrays.toString(componentClasses));
    //使用上一步加载好的bean定义注解读取器加载我们的配置类
    this.reader.register(componentClasses);
    registerComponentClass.end();
}


private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
        @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
        @Nullable BeanDefinitionCustomizer[] customizers) {

    /*创建AnnotatedGenericBeanDefinition实例。目的是将系统中扫描的实例转化为spring的bean(即BeanDefinition) 。

        内部记录当前的class
        并且创建了一个AnnotationMetadata类型对象(实例为StandardAnnotationMetadata)

        实例StandardAnnotationMetadata中记录了目标类的class,创建了一个MergedAnnotations类型对象(实例为TypeMappedAnnotations)

        创建MergedAnnotations类型对象的条件:
            查找的 AnnotatedElement;
            搜索策略 SearchStrategy;
            可重复注解容器 RepeatableContainers;
            注解过滤器 AnnotationFilter;
        */
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    /*根据 @Conditional 注解判断是否跳过注册*/
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
        return;
    }

    abd.setInstanceSupplier(supplier);

    /*解析bean作用域(单例或者原型),如果有@Scope注解,则解析@Scope,没有则默认为单例的bean*/
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);

    /*设置获取到的bean的作用域*/
    abd.setScope(scopeMetadata.getScopeName());

    /*获取bean的名称,如果没有自动的创建一个bean的名称*/
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

    // 处理这五个注解:@LazyInit、@Primary、@dependsOn、@role、@description 用户没有赋值则使用默认赋值
    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

    if (qualifiers != null) {
        for (Class<? extends Annotation> qualifier : qualifiers) {
            if (Primary.class == qualifier) {
                abd.setPrimary(true);
            }
            else if (Lazy.class == qualifier) {
                abd.setLazyInit(true);
            }
            else {
                abd.addQualifier(new AutowireCandidateQualifier(qualifier));
            }
        }
    }

    /*bean的回调处理*/
    if (customizers != null) {
        for (BeanDefinitionCustomizer customizer : customizers) {
            customizer.customize(abd);
        }
    }

    /*创建一个BeanDefinitionHolder实例,并且持有abd,beanName*/
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

    /*是否使用代理模式创建definitionHolder:
    *     否:返回原来的definitionHolder
    *     是:创建一个新的definitionHolder
    * */
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

    /*
    * 将bean定义注册到bean工厂,如果有别名就注册别名
    * */
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

这里就是将我们的配置类转化成bean定义,注册到spring的容器当中。至此spring容器启动过程的第二步已经完成。

以上两步都是准备环境,为了后续初始化容器做准备

刷新容器 refresh()方法

最后一步,也是spring容器启动过程中最重要的一步,是Spring容器启动的关键所在,覆盖了容器从初始化到完成Bean加载的全过程,是容器启动的核心方法。

refresh()方法的主要流程包括:

  1. 初始化容器前的预处理,如启动时间、active标志等
  2. 加载Bean定义,通过加载XML、注解等方式解析并注册Bean定义
  3. 触发BeanFactoryPostProcessor,修改Bean定义元数据
  4. 注册BeanPostProcessor,用于后续Bean实例化过程中的处理
  5. 初始化MessageSource,用于国际化消息解析
  6. 初始化应用事件广播器
  7. 初始化剩余单例非懒加载Bean,触发完整的Bean生命周期
  8. 完成refresh,发布容器刷新完成事件
  9. 注册关闭钩子,以容器关闭时调用销毁方法
public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

            /*刷新之前的准备动作。
                1.记录当前事件
                2.将容器变为激活状态
                3.初始化程序员实现的自己定义的一些资源
                4.验证程序设定的所有必须的属性
                5.初始化早期的事件监听器集合,早期的应用事件集合
                */
            prepareRefresh();

            /*获取容器的bean工厂
            *
            *     刷新前尝试用cas的方式加锁
            *     加锁成功,准备刷新spring容器。
            *     然后获取获取容器的bean工厂(工厂实例为DefaultListableBeanFactory),设置该工厂的id
            * */
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            /*给工厂添加一些配置:
            *     1.添加类加载器
            *     2.添加默认的表达式解析器(如果有),属性编辑注册器
            *     3.添加两个bean的后置处理器(BeanPostProcessor)。’ApplicationContextAwareProcessor‘, ‘ApplicationListenerDetector’
            *     3.处理spring的默认主要接口的默认实现
            *     4.向容器的单例池中添加需要的4个单例bean
            *     5.忽略默认依赖检查
            * */
            prepareBeanFactory(beanFactory);

            try {

                /*空壳方法, 让用户自己实现此方法。
                *
                *     目的是在spring执行所有的后置处理器之前,留给用户对bean工厂做一些操作。如,添加自己的后置处理器
                *     此时还未开始调用bean工厂的后置处理器。bean还未扫描
                * */
                postProcessBeanFactory(beanFactory);

                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");

                // Invoke factory processors registered as beans in the context.
                /*
                * 开始调用bean工厂的后置处理。这里会执行spring两个内置的后置处理器‘ConfigurationClassPostProcessor’,‘EventListenerMethodProcessor’
                *
                *     ConfigurationClassPostProcessor
                *         1.这个处理会扫描并解析我们配置的bean,并封装成BeanDefinitio注入到bean工厂
                *         2.执行我们自定义的后置处理器(实现了这两个接口的BeanDefinitionRegistryPostProcessor,BeanFactoryPostProcessor)
                *        3.将配置文件类使用cglib生成代理类,并增强
                *
                *     EventListenerMethodProcessor
                *         1.收集bean工厂的EventListenerFactory接口,并添加到该处理器内部
                * */
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                /*
                * 注册bean的后置处理器(该处理器的作用是在bean实例化前后提供处理方法)
                *     1.将所有实现了BeanPostProcessor的bean注册到bean工厂
                *     2.调整ApplicationListenerDetector处理器到链表的最后
                * */
                registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();

                /*
                * 初始化MessageSource,spring支持国际化信息:
                *     1.向容器和单例池中注册messageSource实例
                *
                * note:根据客户端的语言,返回对应的信息资源。比如做web程序浏览器端用的中文,那么返回中文相关提示,如果是英文则返回英文相关提示
                * */
                initMessageSource();


                /*
                * 初始化一个默认的事件发布器。
                *     1.向容器和bean工厂的单例池中添加applicationEventMulticaster实例
                * */
                initApplicationEventMulticaster();

                /*
                * 空壳方法,留着子类实现,在此时机提供回调。
                *
                *     目的是在spring刷新时提供回调,让开发者做一些自己的事,如 初始化其他的Bean用的
                *     此时,spring的扫描已经完成,但所有的单例还为开始初始化
                * */
                onRefresh();

                /*
                * 注册监听器:
                *    1.所有实现ApplicationListener接口的监听器
                *     将监听器注册到上面的事件发布器当中
                * */
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                /*
                * 在这里完成bean工厂的初始化!
                *         1.创建容器的单例池,在BeanDefinition中如果处于非懒加载的,单例的bean会在这里创建,这里就是spring的bean的生命周期。
                *         2.添加字符串解析器
                *         3.在实例化单例池之前,先初始化LoadTimeWeaverAware接口的实现类
                * */
                finishBeanFactoryInitialization(beanFactory);

                /*
                * 完成刷新。
                *     1.发布(触发)容器刷新事件
                *     2.清空不需要的缓存,
                *     3.添加,调用生命周期处理器,
                *     4.处理相应的自定义生命周期接口
                * */
                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();
                contextRefresh.end();
            }
        }
    }

prepareRefresh方法

在容器正式启动和加载Bean之前,进行一系列的前置准备和校验工作,为后续的refresh过程做好了初始化,确保了容器可以启动并正常运行

/**
 * Prepare this context for refreshing, setting its startup date and
 * active flag as well as performing any initialization of property sources.
 *
 * 设置容器的启动日期startDateTime
 * 设置active标志,用于标识容器的激活状态
 * 初始化property source abstraction,用于配置属性处理
 * 校验必要的属性设置,如环境environment和配置文件路径
 * 对系统属性和环境变量进行准备处理
 * 对容器内部属性配置的子类做一些准备工作
 * 初始化容器内部一些属性,如容器类加载器、事件处理器等
 * 校验容器内部属性配置的子类的必要设置
 * 存储容器启动阶段的快照,用于容器关闭时显示位标
 * 初始化资源路径,如类路径或证书路径等
 */
protected void prepareRefresh() {
    //记录当前时间,并且设置AnnotationConfigApplicationContext为活动状态
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);

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

    //
    /*
    * 空壳方法,用于程序员定义子类,实现该方法,用于在容器初始化或刷新前,加载一些资源。
    *
    * */
    initPropertySources();


    // see ConfigurablePropertyResolver#setRequiredProperties
    //验证所有必须的属性是否存在,不存在则抛出异常。验证的系统启动参数,如在系统必须要存在的参数,比如你在-D参数中新增了一个参数bmlxx,那么你需要检查它必须存在
    //ac.getEnvironment().setRequiredProperties("bmlxx");
    getEnvironment().validateRequiredProperties();


    //初始化监听器,如果已有一些监听事件则添加到applicationListeners 然后清空
    if (this.earlyApplicationListeners == null) {
        this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    }
    else {
        // Reset local application listeners to pre-refresh state.
        this.applicationListeners.clear();
        this.applicationListeners.addAll(this.earlyApplicationListeners);
    }

    // Allow for the collection of early ApplicationEvents,
    // to be published once the multicaster is available...
    this.earlyApplicationEvents = new LinkedHashSet<>();
}

prepareBeanFactory方法

obtainFreshBeanFactory()方法是获取bean工厂,没什么好说的。prepareBeanFactory方法是为了给上一步获取到的BeanFactory做各种标准配置,以及添加一些内建处理器,初始化后使其处于可工作状态,为后面完成Bean定义加载与实例化做好准备。

/**
 * Configure the factory's standard context characteristics,
 * such as the context's ClassLoader and post-processors.
 * @param beanFactory the BeanFactory to configure
 *                    
 * 设置BeanFactory的class loader为当前context的class loader,方便加载bean类。
 * 设置BeanExpressionResolver,用于解析Bean中的表达式语言如#{...}。
 * 添加PropertyEditorRegistrar实现,用于属性编辑转换。
 * 设置BeanFactory的ResourceLoader,用于加载外部资源文件。
 * 设置BeanFactory的ApplicationEventPublisher,用于事件发布。
 * 注册一些内建的aware接口,如EnvironmentAware、ResourceLoaderAware等。
 * 添加一些BeanPostProcessor实现,如ApplicationContextAwareProcessor等。
 * 注册一些内建的scope,如"prototype"和"singleton" 作用域。
 * 自定义一些内建bean的名称,如environment、systemProperties等。
 * 许多子类会覆盖这个方法定制初始化逻辑。
 */
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {

    //设置bean工厂的类加载器
    beanFactory.setBeanClassLoader(getClassLoader());

    //是否使用spring的表达式,如果使用则添加表达式解析器到bean工厂
    if (!shouldIgnoreSpel) {
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    }

    //添加属性编辑注册器到bean工厂 ,注册器作用未知
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    //添加spring的后置处理器(每次添加都会在集合的末尾),此后置处理器用来实现bean实现aware接口的回调
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

    //添加需要忽略的依赖检查到HashSet集合
    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.ignoreDependencyInterface(ApplicationStartupAware.class);

    //添加到resolvableDependencies的集合当中,目的时为了解决注入时一个接口有多个实现,默认自动注入registerResolvableDependency第二个参数的实现
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    //添加spring的后置处理器
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // Detect a LoadTimeWeaver and prepare for weaving, if found.
    if (!NativeDetector.inNativeImage() && 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()));
    }

    //给spring容器注册系统需要的一些单例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());
    }
    if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
        beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
    }
}

invokeBeanFactoryPostProcessors方法

该方法的作用是执行BeanFactoryPostProcessor。从字面意思看这个方法就是调用bean工厂的后置处理器,在这里为后续的Bean创建提供了扩展点,允许开发人员对Bean的定义进行干预和修改,以满足特定的需求。例如,可以使用BeanFactory后处理器来动态注入属性值、更改Bean的作用域、创建代理对象等等。

这个方法极其复杂,也是启动过程中非常重要的方法,在这个方法中,完成了我们配置类的扫描,将我们配置的spring的bean扫描到容器中(此时还没有形成bean,以资源的方式存储)

这个方法执行的主要步骤包括:

  1. 获取所有已注册的BeanFactory后处理器(BeanFactoryPostProcessors)。
  2. 按照优先级顺序排序这些后处理器(如果它们有优先级)。
  3. 依次调用每个后处理器的 postProcessBeanFactory() 方法,将BeanFactory作为参数传递给它们。
  4. 后处理器可以通过修改Bean定义或者执行其他自定义逻辑来影响容器中Bean的配置。
/**
 * 这里会将bean工厂后置处理器分成两类:
 *          a: ’BeanDefinitionRegistryPostProcessors‘
 *         b: ’BeanFactoryPostProcessor‘
 *
 *     1.先从参数2中将后置处理器分成上述两类,放到两类集合中。
 *         这里如果有a类,就立即执行
 *     2.再从bean工厂中先找a类,找到之后再根据排序接口,按序执行。执行顺序@riorityOrdered->Ordered->没有实现排序接口的
 *     3.再从bean工厂找b类,根据上述顺序执行
 *
 *     note:从bean工厂中找到的a,b两类,可能没有实例化,这里调用getBean()方法 提前实例化配置类(就是我们的配置文件类)
 *
 * @param beanFactory bean工厂
 * @param beanFactoryPostProcessors 要执行的后置处理器的集合
 */
public static void invokeBeanFactoryPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {


    // 记录已经处理过的BeanDefinitionRegistryPostProcessors后置处理器
    Set<String> processedBeans = new HashSet<>();

    /*将spring容器自带的后置处理器分类
    *     1.如果实现了BeanDefinitionRegistryPostProcessor接口,那么放到registryProcessors集合,并且立即执行自定义的处理方法
    *     2.如果实现了BeanFactoryPostProcessor接口,放到regularPostProcessors集合,暂不执行
    * */
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            }
            else {
                regularPostProcessors.add(postProcessor);
            }
        }

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        // Separate between BeanDefinitionRegistryPostProcessors that implement
        // PriorityOrdered, Ordered, and the rest.
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

        // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.

        /*这里是先调用实现了BeanDefinitionRegistryPostProcessor接口并且实现了PriorityOrdered(排序)接口的后置处理器
            1.找到bean工厂中实现了BeanDefinitionRegistryPostProcessor接口的bean名称集合。这里找到的bean是spring容器自带的
             2.再遍历是否实现了排序接口,如果实现了就将该bean加入集合,bean名称加入set集合
            3.将bean名称加入set集合的目的是防止后置处理器重复执行
        */
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                //note:所有配置类(就是我们用来替代xml的文件配置类)会在这里提前初始化,因为调用了beanFactory.getBean()方法
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }

        //根据指定的排序规则排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);

        //全部加入之前分类的registryProcessors集合当中
        registryProcessors.addAll(currentRegistryProcessors);

        /*开始调用BeanDefinitionRegistryPostProcessor类型的后置处理器
        *     上面把实现了BeanDefinitionRegistryPostProcessor接口的后置处理器归类,然后在此处集体调用并执行
        *
        * node:初始化时这里执行的是spring内置的‘配置类后置处理器’ ConfigurationClassPostProcessor。
        *         这个配置类会扫描所有我们配置的类,并将bean包装成bean定义(beanDefinition)后注册到bean工厂
        * */
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());

        //处理完成清空集合
        currentRegistryProcessors.clear();

        /*
        * 这里再调用实现了BeanDefinitionRegistryPostProcessor接口但是实现了Ordered(排序)接口的后置处理器,逻辑同上。
        *
        * node:再次调用beanFactory.getBeanNamesForType获取实现了后置处理的器接口,有可能上面解析时会加入新的后置处理器接口
        *
        * */
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            //上面可能会获取到已经处理过的处理器,在这过滤掉。 并且该处理器实现了Ordered
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
        currentRegistryProcessors.clear();

        //最后处理剩下所有的BeanDefinitionRegistryPostProcessors后置处理器,逻辑同上
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                    reiterate = true;
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
            currentRegistryProcessors.clear();
        }

        // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
        /*
        * 这才开始执行BeanFactoryPostProcessor接口中的postProcessBeanFactory方法。
        *
        *     1.BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口。
        *     2.上面执行完BeanDefinitionRegistryPostProcessor接口时,并没执行BeanFactoryPostProcessor接口内容(是BeanDefinitionRegistryPostProcessor接口的实现类也必定是BeanFactoryPostProcessor的实现类)
        *        所以两个集合都需要执行
        *   3.再执行BeanFactoryPostProcessor接口中的postProcessBeanFactory方法
        *
        * node:初始化时,这里也会执行的是spring内置的‘配置类后置处理器’ ConfigurationClassPostProcessor的postProcessBeanFactory方法,会使用cglib生成代理类增强配置类
        * */
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    else {
        // Invoke factory processors registered with the context instance.
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let the bean factory post-processors apply to them!
    /*
    * 这里重新在bean工厂获取BeanFactoryPostProcessor接口的实现类
    *      1.因为上面可能执行配置类后置处理器,这个类会扫描系统中的我们配置的bean加入到容器
    * */
    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    /*
    * 在这 将BeanFactoryPostProcessors接口的实现类分成三类,并分别执行
    *     1.实现了PriorityOrdered接口的
    *     2.实现了Ordered接口
    *     3.其他的
    * */
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
        if (processedBeans.contains(ppName)) {


            // 空的if代码块,目的是为了过滤掉上面已经处理过的类.下面分三类

        }
        else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    /*
    * 开始调用BeanFactoryPostProcessors的后置处理器,跟上面一样分为三类。
    *     先执行PriorityOrdered排序,
    *     再执行Ordered排序
    *     最后执行没有排序的
    * */
    // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    /*
     * 在这里,初始化时这里有一个spring内部的处理器要执行:事件监听方法处理器
     *         1.目的是为了初始化该处理器内部的eventListenerFactories属性
     *         2.此处理器执行时找到bean工厂的所有EventListenerFactory,然后排序,再赋值到事件监听工厂
     * */
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

    // Clear cached merged bean definitions since the post-processors might have
    // modified the original metadata, e.g. replacing placeholders in values...
    //后置处理器调用完毕。清除mergedBeanDefinitions,上述处理可能会改变metadata的数据
    beanFactory.clearMetadataCache();
}

registerBeanPostProcessors方法

这个方法就是将实现了BeanPostProcessor接口的后置处理器注册到容器当中。在这里分为两类后置处理器,一种是spring的内置处理器,另外一种是开发者自己定义的处理器,按照一定的顺序注册到Spring容器中。

例如处理@PostConstruct@PreDestroy@Required等这些注解的处理器

步骤:

  1. 获取所有已注册的BeanPostProcessor。这些BeanPostProcessor分上述两类。
  2. 将BeanPostProcessor按照一定的顺序注册到Spring容器中。这个顺序通常由BeanPostProcessor的实现类或配置属性来决定。
  3. 将注册的BeanPostProcessor添加到容器的BeanPostProcessor列表中,以便在后续的Bean实例化和初始化过程中被调用。
public static void registerBeanPostProcessors(
        ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    // WARNING: Although it may appear that the body of this method can be easily
    // refactored to avoid the use of multiple loops and multiple lists, the use
    // of multiple lists and multiple passes over the names of processors is
    // intentional. We must ensure that we honor the contracts for PriorityOrdered
    // and Ordered processors. Specifically, we must NOT cause processors to be
    // instantiated (via getBean() invocations) or registered in the ApplicationContext
    // in the wrong order.
    //
    // Before submitting a pull request (PR) to change this method, please review the
    // list of all declined PRs involving changes to PostProcessorRegistrationDelegate
    // to ensure that your proposal does not result in a breaking change:
    // https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22

    /*
    * 查找bean工厂中BeanPostProcessor接口的结合
    * */
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // Register BeanPostProcessorChecker that logs an info message when
    // a bean is created during BeanPostProcessor instantiation, i.e. when
    // a bean is not eligible for getting processed by all BeanPostProcessors.
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // Separate between BeanPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    /*
    * 将找到的BeanPostProcessor接口的实现类 分成四类。按照分类顺序注册到bean工厂的后置处理器(此容器是一个有序链表)
    *     1.实现了PriorityOrdered接口的先注册到最前面
    *     2.再注册实现了Ordered接口的
    *     3.再注册没有实现上面两个接口的
    *     4.在执行上述接口实现类的同时,如果还实现了MergedBeanDefinitionPostProcessor接口,那么会将放入单独的集合,重新注册到链表容器的最后
    * */
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // First, register the BeanPostProcessors that implement PriorityOrdered.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // Next, register the BeanPostProcessors that implement Ordered.
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // Now, register all regular BeanPostProcessors.
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // Finally, re-register all internal BeanPostProcessors.
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // Re-register post-processor for detecting inner beans as ApplicationListeners,
    // moving it to the end of the processor chain (for picking up proxies etc).
    /*
    *  重新添加ApplicationListenerDetector到bean工厂,目的是为了加到集合的尾部
    *
    * */
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

initMessageSource方法

初始化国际消息,这个方法的作用就是Spring框架用于支持国际化(i18n)和本地化(l10n)的一个重要组件。它允许应用程序在不同的语言和区域环境下加载不同的消息文本,以提供多语言支持。

/**
 * Initialize the MessageSource.
 * Use parent's if none defined in this context.
 * 
 * 检查容器中是否已经存在名为 "messageSource" 的Bean。如果已经存在,将其作为消息源。这意味着您可以在Spring配置中自定义消息源,而不是使用默认配置。
 *
 * 如果容器中没有找到 "messageSource" 的Bean,那么默认情况下,Spring会创建一个 DelegatingMessageSource 类型的Bean作为消息源,并将其注册到容器中。DelegatingMessageSource 是一个复合消息源,它可以包含多个消息源,并按照优先级顺序查找消息。
 *
 * 设置消息源的父级消息源(Parent Message Source)。这是为了支持消息源的层次结构,允许消息的继承和覆盖。
 *
 * 初始化消息源的各种属性,如消息源的编码、默认语言等。
 */
protected void initMessageSource() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    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.
                hms.setParentMessageSource(getInternalParentMessageSource());
            }
        }
        if (logger.isTraceEnabled()) {
            logger.trace("Using MessageSource [" + this.messageSource + "]");
        }
    }
    else {
        // Use empty MessageSource to be able to accept getMessage calls.
        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 + "]");
        }
    }
}

initApplicationEventMulticaster方法

用于初始化应用程序事件多播器(ApplicationEventMulticaster)。应用程序事件多播器是Spring框架中用于处理和传播应用程序事件的关键组件。

一旦初始化完成,它允许应用程序中的各个组件发布事件,同时让其他组件监听并响应这些事件。通常,开发人员可以使用Spring的 ApplicationEventPublisher 接口来发布事件,而事件监听器则会实现 ApplicationListener 接口来监听和处理事件

/**
 * Initialize the ApplicationEventMulticaster.
 * Uses SimpleApplicationEventMulticaster if none defined in the context.
 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
 * 
 * 
 * 检查容器中是否已经存在名为 "applicationEventMulticaster" 的Bean。如果已经存在,将其作为应用程序事件多播器。这意味着您可以在Spring配置中自定义应用程序事件多播器,而不是使用默认配置。
 *
 * 如果容器中没有找到 "applicationEventMulticaster" 的Bean,那么默认情况下,Spring会创建一个 SimpleApplicationEventMulticaster 类型的Bean作为应用程序事件多播器,并将其注册到容器中。SimpleApplicationEventMulticaster 是一个简单的多播器,它可以广播事件给所有注册的监听器。
 *
 * 初始化应用程序事件多播器的各种属性,如执行事件监听器的线程池配置、异常处理策略等。
 */
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() + "]");
        }
    }
}

registerListeners方法

注册应用程序事件监听器,以便在应用程序中监听和响应事件,实现组件间的通信。这个方法是将监听器注册到上一步的ApplicationEventMulticaster当中,这样就可以监听并响应应用程序中发生的各种事件

/**
 * Add beans that implement ApplicationListener as listeners.
 * Doesn't affect other listeners, which can be added without being beans.
 * 
 * 从容器中查找所有标注有@EventListener的Bean,注册为应用事件监听器。
 * 如果配置了applicationListenerDetector属性,会使用该检测器进一步查找监听器。
 * 将查找到的监听器注册到容器的事件广播器中。
 * 如果有ApplicationEventMulticaster的bean,则将其设置为事件广播器。
 * 最后将已注册的监听器初始化并调用contextRefreshedEvent回调通知
 */
protected void registerListeners() {
    // Register statically specified listeners first.
    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);
    }

    // Publish early application events now that we finally have a multicaster...
    /*
    * 发布早期的事件
    * */
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

finishBeanFactoryInitialization方法

finishBeanFactoryInitialization() 方法是 Spring 容器初始化过程中的最后一步,确保了在容器启动后,所有需要立即可用的 Bean 都已准备就绪

  1. 完成单例(Singleton)Bean 的初始化:该方法会遍历容器中所有的 Bean 定义,找到所有需要在容器启动时初始化的单例 Bean,并确保它们被实例化、初始化、依赖注入等。这里就是spring的bean的生命周期

  2. 触发初始化回调方法:对于单例 Bean,Spring 会调用其初始化回调方法(例如,@PostConstruct 方法或实现 InitializingBean 接口的 afterPropertiesSet() 方法)来执行自定义初始化逻辑。

  3. 实现懒加载:对于懒加载的单例 Bean,Spring 会根据需要实例化和初始化,而不是在容器启动时。

  4. 完成 BeanPostProcessor 的注册和应用:在容器启动后,BeanPostProcessor(Bean 后处理器)会被调用,这些后处理器可以修改 Bean 的配置和行为。

  5. 触发事件:Spring 可能会在此时触发一些事件,通知监听器容器已经启动完成或某些 Bean 已经初始化完成。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // Initialize conversion service for this context.
    /*
    * 查看bean工厂中是否有一个conversionService的bean,如果有就注册到bean工厂的转化服务当中
    * */
    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 BeanFactoryPostProcessor
    // (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
    // at this point, primarily for resolution in annotation attribute values.
    /*
    * 如果之前没有注册过, 注册一个字符串解析器
    * */
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
            @Override
            public String resolveStringValue(String strVal) {
                return AbstractApplicationContext.this.getEnvironment().resolvePlaceholders(strVal);
            }
        });
    }

    // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

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

    // Allow for caching all bean definition metadata, not expecting further changes.
    /*
    * 修改状态,冻结bean。所有的beanDefinition不会再被修改了,因为马上要实例化了
    * */
    beanFactory.freezeConfiguration();

    // Instantiate all remaining (non-lazy-init) singletons.
    /*
    * 实例化剩下的非懒加载的单例bean
    * */
    beanFactory.preInstantiateSingletons();
}

finishRefresh方法

是Spring 容器刷新过程的最后一步,用于一些扫尾工作,执行一些额外的清理和通知操作,触发容器已经刷新完成的事件、启动生命周期处理器以及完成容器的刷新

protected void finishRefresh() {
    // Clear context-level resource caches (such as ASM metadata from scanning).
    /*
    * 清除资源缓存。该集合中存在一个元数据读取器,存放我们扫描的bean的类相关数据,类的真实文件信息
    *
    * */
    clearResourceCaches();
    /*
    * 向容器和单例池中添加一个默认的生命周期处理器
    * */
    initLifecycleProcessor();

    // Propagate refresh to lifecycle processor first.
    /*
    * 实现所有的生命周期接口的回调。
    *     生命周期接口的扩展,用于哪些需要在ApplicationContext刷新和启动/或按特定顺序关闭时启动的对象
    *     保证容器在启动后调用start方法开始生命周期,并且在Spring关闭的时候调用stop方法来结束生命周期,通常用来配置后台程序,比如MQ进行轮询等
    * */
    getLifecycleProcessor().onRefresh();

    /*
    * 发布容器刷新事件:
    *     1.用户可以自己实现监听器(ApplicationListener),监听这个事件(ContextRefreshedEvent),在容器初始化完成或刷新完成时调用。
    *     2.可同步或异步触发
    * */
    publishEvent(new ContextRefreshedEvent(this));

    // Participate in LiveBeansView MBean, if active.
    if (!NativeDetector.inNativeImage()) {
        LiveBeansView.registerApplicationContext(this);
    }
}

这一步完成,标志着容器已经准备好接受应用程序的请求,可以正常运行。


文章作者: Needle
转载声明:本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Needle !
  目录
  评论