Spring源码系列——容器的启动过程(三)

一. 前言

Spring源码系列——容器的启动过程(一)中,我们解析了构造方法.
Spring源码系列——容器的启动过程(二)中,我们解析了注册方法.
本篇文章,分析最后一个方法refresh()!

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
   
    this();
    register(componentClasses);
    // 3.刷新整个容器
    refresh();
}

二. refresh()方法解析

构造方法中, 前面两步已经做了很多事情了, 但这些事情都是准备工作. 比起refresh()而言, 还是小巫见大巫. 在refresh()方法中,包含着各后置处理的作用 / 调用时机; Bean的诞生过程; 循环依赖如何解决以及Spring的其他组件使用等. 接下来迎接风暴!

// refresh()本身是一个聚合方法, 具体的功能都委托给了各个子方法.
public void refresh() throws BeansException, IllegalStateException {
   
    synchronized (this.startupShutdownMonitor) {
   
        // 1.在刷新容器之前,做一些基础的处理. 不难
        prepareRefresh();

        // 2. 获取刷新后的beanFactory.注意:这里并不是要把当前的beanFactory全部刷新,只是刷新部分数据.不然之前的准备工作岂不是白做了. 不难
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// 3. 准备BeanFactory. 重要!!!
        prepareBeanFactory(beanFactory);

        try {
   
            // 4. 空方法 Spring后版本可能会用
            postProcessBeanFactory(beanFactory);
			
            // 5. 调用后置处理器 重要!!!
            invokeBeanFactoryPostProcessors(beanFactory);

            // 6. 注册后置处理的Bean到容器当中 重要!!!
            registerBeanPostProcessors(beanFactory);

            // 7. 初始化MessageSource并将其bean注入到容器中
            initMessageSource();

            // 8. 初始化事件多播器并将其bean注入到容器中
            initApplicationEventMulticaster();

            // 9. 在特定上下文子类中初始化其他特殊bean. 当前是空方法, Spring后续版本可能会用
            onRefresh();

            // 10. 注册监听器到容器中
            registerListeners();

            // 11. 实例化所有剩余的bean(非延迟)到容器中 重要!!!
            finishBeanFactoryInitialization(beanFactory);

            // 12. 最后, 发布容器刷新完成事件
            finishRefresh();
        }

        catch (BeansException ex) {
   
           // 异常情况下, 销毁容器中所有的bean
            destroyBeans();
            cancelRefresh(ex);
            throw ex;
        }

        finally {
   
            // 清除一些不必要的缓存
            resetCommonCaches();
        }
    }
}

2.1 prepareRefresh()

protected void prepareRefresh() {
   
    // 设置激活状态,启动时间
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);

    // 初始化资源必要的资源. 目前是空方法. Spring后续版本可能会启用.
    initPropertySources();

    // 校验系统环境/JVM环境当中的必要参数
    getEnvironment().validateRequiredProperties();

    // 存储预刷新的ApplicationListeners. 实际上就是一个empty set
    if (this.earlyApplicationListeners == null) {
   
        this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    }
    else {
   
        this.applicationListeners.clear();
        this.applicationListeners.addAll(this.earlyApplicationListeners);
    }

    // 允许收集早期的ApplicationEvent,一旦多播器可用,便会发布. 实际上这里也是一个empty set
    this.earlyApplicationEvents = new LinkedHashSet<>();
}

2.2 prepareBeanFactory()

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   
    // 设置beanFactory的类加载器. 实际上,这里的类加载器和前文中所提到的类加载器是一样的.
    beanFactory.setBeanClassLoader(getClassLoader());
    // 设置beanFactory当中的表达式语言解析器. 比如@Value中的表达式就是这里设置的解析器来解析的.
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    // 设置beanFactory当中的属性编辑器.比如在配置文件中配置了一个"2020-01-01"的日期类型字符串,
    // 正常情况下,Spring无法解析为Date类型,因此可以通过自定义属性编辑器的方式来转换.这就是属性编辑器的作用.
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
	
    // 重要!!! 这里添加了一个ApplicationContextAwareProcessor到BeanFactory的BeanPostProcessors中.
    // 注意,这里只是添加到后置处理列表,并没有将其解析为beanDefinition,更没有解析为bean注入到容器当中.具体解析时机,后面会提到.
    // 到这里, BeanFactory中的BeanPostProcessors中迎来了第1个后置处理器.(注意,并没有添加到BeanDefinitionMap中)
    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);

    // 这里提前注册已解析的依赖,目

你可能感兴趣的:(Spring,Framework,spring,java)