spring中的refresh函数

背景

refresh函数是spring容器启动的核心中的核心, Spring容器创建之后,会调用它的refresh方法刷新Spring应用的上下文。
先来看一下源码
此部分源码,把容器的刷新步骤体现得非常的清晰,十足的面向对象编程

@Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            //容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性等
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            // 获取新的beanFactory(默认实现是DefaultListableBeanFactory,在创建容器的时候创建的),销毁原有beanFactory、为每个bean生成BeanDefinition等  
            // 注意,此处是获取新的,销毁旧的,这就是刷新的意义
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
//BeanFactory的预准备工作(BeanFactory进行一些设置,比如context的类加载器,BeanPostProcessor和XXXAware自动装配等)
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
    //BeanFactory准备工作完成后进行的后置处理工作
                //模板方法,允许在子类中对beanFactory进行后置处理。
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                //实例化并调用所有注册的beanFactory后置处理器(实现接口BeanFactoryPostProcessor的bean)。
                //在beanFactory标准初始化之后执行  例如:PropertyPlaceholderConfigurer(处理占位符)
                invokeBeanFactoryPostProcessors(beanFactory);

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

                // Initialize message source for this context.
                //初始化国际化工具类MessageSource
                initMessageSource();

                // Initialize event multicaster for this context.
                // 初始化事件派发器
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                //模板方法,在容器刷新的时候可以自定义逻辑(子类自己去实现逻辑),不同的Spring容器做不同的事情, 如创建Tomcat,Jetty等WEB服务器
                onRefresh();

                // Check for listener beans and register them.
                //注册监听器(就是注册实现了ApplicationListener接口的监听器bean,这些监听器是注册到ApplicationEventMulticaster中的),并且广播early application events,也就是早期的事件
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                //非常重要。。。实例化所有剩余的(非懒加载)单例Bean。(也就是我们自己定义的那些Bean们)
                //比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化  扫描的 @Bean之类的
                //实例化的过程各种BeanPostProcessor开始起作用~~~~~~~~~~~~~~
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                //refresh做完之后需要做的其他事情
                //清除上下文资源缓存(如扫描中的ASM元数据)
                //初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)。
                //发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
                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.
                //如果刷新失败那么就会将已经创建好的单例Bean销毁掉
                destroyBeans();

                // Reset 'active' flag.
                //重置context的活动状态 告知是失败的
                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...
                // 失败与否,都会重置Spring内核的缓存。因为可能不再需要metadata给单例Bean了。
                resetCommonCaches();
            }
        }
    }
  • 1 prepareRefresh方法

表示在真正做refresh操作之前需要准备做的事情:

  • 设置Spring容器的启动时间,
  • 开启活跃状态,撤销关闭状态,。
  • 初始化context environment(上下文环境)中的占位符属性来源。
  • 验证环境信息里一些必须存在的属性
protected void prepareRefresh() {
        //记录容器启动时间,然后设立对应的标志位
        this.startupDate = System.currentTimeMillis();
        this.closed.set(false);
        this.active.set(true);

        // 打印info日志:开始刷新this此容器了
        if (logger.isInfoEnabled()) {
            logger.info("Refreshing " + this);
        }

        // Initialize any placeholder property sources in the context environment
        // 这是扩展方法,由子类去实现,可以在验证之前为系统属性设置一些值可以在子类中实现此方法
        // 因为我们这边是AnnotationConfigApplicationContext,可以看到不管父类还是自己,都什么都没做,所以此处先忽略
        initPropertySources();

        // Validate that all properties marked as required are resolvable
        // see ConfigurablePropertyResolver#setRequiredProperties
        //这里有两步,getEnvironment(),然后是是验证是否系统环境中有RequiredProperties参数值 如下详情
        // 然后管理Environment#validateRequiredProperties 后面在讲到环境的时候再专门讲解吧
        // 这里其实就干了一件事,验证是否存在需要的属性
        getEnvironment().validateRequiredProperties();

        // Allow for the collection of early ApplicationEvents,
        // to be published once the multicaster is available...
        // 初始化容器,用于装载早期的一些事件
        this.earlyApplicationEvents = new LinkedHashSet<>();
    }
  • 2 obtainFreshBeanFactory()

实际上就是重新创建一个bean工厂,并销毁原工厂。主要工作是创建DefaultListableBeanFactory实例,解析配置文件,注册Bean的定义信息

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (logger.isDebugEnabled()) {
            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }

在spring中,基本上各司其职,每个类都有每个类的作用。其中refreshBeanFactory()是具体的刷新BeanFactory,负责这个工作做在类AbstractRefreshableApplicationContext#refreshBeanFactory中,顾名思义这是专门用来刷新的:
refreshBeanFactory()

    @Override
    protected final void refreshBeanFactory() throws BeansException {
        // 判断是否已经存在BeanFactory,存在则销毁所有Beans,并且关闭BeanFactory
        // 避免重复加载BeanFactory
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            // 创建具体的beanFactory,这里创建的是DefaultListableBeanFactory,最重要的beanFactory spring注册及加载bean就靠它
            // createBeanFactory()这个方法,看下面,还有得说的
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
        
            // 这句比较简单,就是把当前旧容器的一些配置值复制给新容器 
            // allowBeanDefinitionOverriding属性是指是否允对一个名字相同但definition不同进行重新注册,默认是true。
            // allowCircularReferences属性是指是否允许Bean之间循环引用,默认是true.
            // 这两个属性值初始值为空:复写此方法即可customizeBeanFactory
            customizeBeanFactory(beanFactory);
            
            // 这个就是最重要的了,加载所有的Bean配置信息,具体如下详细解释
            // 它属于模版方法,由子类去实现加载的方式
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }

createBeanFactory()

// 创建的时候就是new了一个工厂:DefaultListableBeanFactory   这个时候工厂里面所有东西都是默认值,很多还没有完成初始化属性的设置呢
    protected DefaultListableBeanFactory createBeanFactory() {
        return new DefaultListableBeanFactory(getInternalParentBeanFactory());
    }
    
    // 给设置父的BeanFactory,若存在的话
    public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
        this();
        setParentBeanFactory(parentBeanFactory);
    }

    // 父类空构造器有这么些语句
    public AbstractAutowireCapableBeanFactory() {
        super();
        
        // 这里是重点。忽略自动装配。这里指定的都是接口。什么意思呢?
        // ignoreDependencyInterface的真正意思是在自动装配时忽略指定接口的实现类中,对外的依赖。(这里面注意:@Autowired和它的关系,其实是有坑的,后续会专门讲解这个坑)
        ignoreDependencyInterface(BeanNameAware.class);
        ignoreDependencyInterface(BeanFactoryAware.class);
        ignoreDependencyInterface(BeanClassLoaderAware.class);
    }
    
    //找到父的,若存在就返回 若存在父容器就存在父的BeanFactory
    @Nullable
    protected BeanFactory getInternalParentBeanFactory() {
        return (getParent() instanceof ConfigurableApplicationContext) ?
                ((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent();
    }

依赖忽略

image.png

AnnotationConfigWebApplicationContext#loadBeanDefinitions()方法,加载Bean的定义 (XmlWebApplicationContext的实现不一样,因为它是加载xml配置文件)

@Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
        // 初始化这个脚手架 其实就是直接new出实例。具体做的工作,下面有相关博文链接
        AnnotatedBeanDefinitionReader reader = getAnnotatedBeanDefinitionReader(beanFactory);
        ClassPathBeanDefinitionScanner scanner = getClassPathBeanDefinitionScanner(beanFactory);

        // 生成Bean的名称的生成器,如果自己没有setBeanNameGenerator(可以自定义),这里目前为null
        BeanNameGenerator beanNameGenerator = getBeanNameGenerator();
        if (beanNameGenerator != null) {
            reader.setBeanNameGenerator(beanNameGenerator);
            scanner.setBeanNameGenerator(beanNameGenerator);
            //若我们注册了beanName生成器,那么就会注册进容器里面
            beanFactory.registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);
        }
        
        //这是给reader和scanner注册scope的解析器  此处为null
        ScopeMetadataResolver scopeMetadataResolver = getScopeMetadataResolver();
        if (scopeMetadataResolver != null) {
            reader.setScopeMetadataResolver(scopeMetadataResolver);
            scanner.setScopeMetadataResolver(scopeMetadataResolver);
        }

        // 此处注意了:annotatedClasses和basePackages一般是选其一(当然看到此处,他们是可以并存的)
        //我们可以自己指定annotatedClasses 配置文件,同时也可以交给下面扫描
        if (!this.annotatedClasses.isEmpty()) {
            
            // 这里会把所有的配置文件输出=======info日志  请注意观察控制台
            if (logger.isInfoEnabled()) {
                logger.info("Registering annotated classes: [" +
                        StringUtils.collectionToCommaDelimitedString(this.annotatedClasses) + "]");
            }
            
            // 若是指明的Bean,就交给reader去处理,至于怎么处理,见上篇博文的doRegisterBean去怎么解析每一个Config Bean的
            reader.register(ClassUtils.toClassArray(this.annotatedClasses));
        }
        
        // 也可以是包扫描的方式,扫描配置文件的Bean
        if (!this.basePackages.isEmpty()) {
            // 输出对应的info日志
            if (logger.isInfoEnabled()) {
                logger.info("Scanning base packages: [" +
                        StringUtils.collectionToCommaDelimitedString(this.basePackages) + "]");
            }
            
            // 这里重要了,scan方法具体做了什么事,上篇博文也有详细的介绍,请参阅
            scanner.scan(StringUtils.toStringArray(this.basePackages));
        }
        
        // 此处的意思是,也可以以全类名的形式注册。比如可以调用setConfigLocations设置(这在xml配置中使用较多)  可以是全类名,也可以是包路径
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {
            for (String configLocation : configLocations) {
                try {
                    Class clazz = ClassUtils.forName(configLocation, getClassLoader());
                    reader.register(clazz);
                } catch (ClassNotFoundException ex) {
                    // 发现不是全类名,那就当作包扫描吧
                    int count = scanner.scan(configLocation);
                }
            }
        }
    }

加载beanDefinition时候会用到AnnotatedBeanDefinitionReader reader , ClassPathBeanDefinitionScanner scanner ,可以参考
https://blog.csdn.net/f641385712/article/details/88059145
现在BeanFactory已经创建了,并且Config配置文件的Bean定义已经注册完成了(备注:其它单例Bean是还没有解析的~~~~)
显然,下面的步骤大都把BeanFactory传进去了,都是基于此Bean工厂的了~~~

  • 3 prepareBeanFactory(beanFactory)

上面已经把工厂建好了,但是还不能投入使用,因为工厂里什么都没有,还需要配置一些东西。这个个方法是配置工厂的标准上下文特征(比如类加载器, 表达式语言,添加部分BeanPostProcessor, 处理一些aware接口(依赖忽略))和post-processors后处理器。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 设置beanFactory的classLoader为当前context的classLoader
        beanFactory.setBeanClassLoader(getClassLoader());
        // 设置EL表达式解析器(Bean初始化完成后填充属性时会用到)
        // spring3增加了表达式语言的支持,默认可以使用#{bean.xxx}的形式来调用相关属性值
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        // 设置属性注册解析器PropertyEditor 这个主要是对bean的属性等设置管理的一个工具
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
        
        // 将当前的ApplicationContext对象交给ApplicationContextAwareProcessor类来处理,从而在Aware接口实现类中的注入applicationContext等等
        // 添加了一个处理aware相关接口的beanPostProcessor扩展,主要是使用beanPostProcessor的postProcessBeforeInitialization()前置处理方法实现aware相关接口的功能
        // 类似的还有ResourceLoaderAware、ServletContextAware等等等等
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        // 下面是忽略的自动装配(也就是实现了这些接口的Bean,不要Autowired自动装配了)
        // 默认只有BeanFactoryAware被忽略,所以其它的需要自行设置
        // 因为ApplicationContextAwareProcessor把这5个接口的实现工作做了(具体你可参见源码) 所以这里就直接忽略掉
        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的类,就注册beanFactory
        //  如果是ResourceLoader、ApplicationEventPublisher、ApplicationContext等等就注入当前对象this(applicationContext对象)
        
        // 此处registerResolvableDependency()方法注意:它会把他们加入到DefaultListableBeanFactory的resolvableDependencies字段里面缓存这,供后面处理依赖注入的时候使用 DefaultListableBeanFactory#resolveDependency处理依赖关系
        // 这也是为什么我们可以通过依赖注入的方式,直接注入这几个对象比如ApplicationContext可以直接依赖注入
        // 但是需要注意的是:这些Bean,Spring的IOC容器里其实是没有的。beanFactory.getBeanDefinitionNames()和beanFactory.getSingletonNames()都是找不到他们的,所以特别需要理解这一点
        // 至于容器中没有,但是我们还是可以@Autowired直接注入的有哪些,请看下图:
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        // 注册这个Bean的后置处理器:在Bean初始化后检查是否实现了ApplicationListener接口
        // 是则加入当前的applicationContext的applicationListeners列表 这样后面广播事件也就方便了
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));


        // 检查容器中是否包含名称为loadTimeWeaver的bean,实际上是增加Aspectj的支持
        // AspectJ采用编译期织入、类加载期织入两种方式进行切面的织入
        // 类加载期织入简称为LTW(Load Time Weaving),通过特殊的类加载器来代理JVM默认的类加载器实现
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            // 添加BEAN后置处理器:LoadTimeWeaverAwareProcessor
            // 在BEAN初始化之前检查BEAN是否实现了LoadTimeWeaverAware接口,
            // 如果是,则进行加载时织入,即静态代理。
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            // Set a temporary ClassLoader for type matching.
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        // 注入一些其它信息的bean,比如environment、systemProperties、SystemEnvironment等
        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());
        }
    }

说个小细节:@Autowiredh和@Qualifier一起是用时,@Qualifier的值需保证容器里一定有,否则启动报错


image.png
  • 第四步 postProcessBeanFactory(beanFactory)

上面对bean工厂进行了许多配置,现在需要对bean工厂进行一些处理。不同的Spring容器做不同的操作模版方法。因为beanFactory都准备好了,子类可以自己去实现自己的逻辑。
比如一些web的ApplicationContext,就实现了自己的逻辑,做一些自己的web相关的事情。此处我们就是web环境下,因此会进来AbstractRefreshableWebApplicationContext#postProcessBeanFactory方法:

    @Override
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        //注册ServletContextAwareProcessor 这样任意Bean都可以很方便的获取到ServletContext了  同时忽略另外两个,因为ServletContextAwareProcessor 都把事情都做了
        beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
        beanFactory.ignoreDependencyInterface(ServletContextAware.class);
        beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
    
        //注册web环境,包括request、session、golableSession、application
        WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
        //注册servletContext、contextParamters、contextAttributes  、servletConfig单例bean
        WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
    }

第5步 invokeBeanFactoryPostProcessors(beanFactory)

invokeBeanFactoryPostProcessors执行BeanFactory后置处理器,当然前提是你已经在容器中注册过此处理器了。
先介绍两个接口:
BeanFactoryPostProcessor:用来修改Spring容器中已经存在的bean的定义,使用ConfigurableListableBeanFactory对bean进行处理
BeanDefinitionRegistryPostProcessor:继承BeanFactoryPostProcessor,作用跟BeanFactoryPostProcessor一样,只不过是使用BeanDefinitionRegistry对bean进行处理
在Spring容器中找出实现了BeanFactoryPostProcessor接口的processor并执行。Spring容器会委托给PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法执行。

** invokeBeanFactoryPostProcessors方法总结来说就是从Spring容器中找出BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor接口的实现类并按照一定的规则顺序进行执行其中ConfigurationClassPostProcessor这个BeanDefinitionRegistryPostProcessor优先级最高,它会对项目中的@Configuration注解修饰的类(@Component、@ComponentScan、@Import、@ImportResource修饰的类也会被处理)进行解析,解析完成之后把这些bean注册到BeanFactory中**。需要注意的是这个时候注册进来的bean还没有实例化。

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        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)
        // 这里就是定制:如果loadTimeWeaver这个Bean存在,那么就会配置上运行时织入的处理器LoadTimeWeaverAwareProcessor
        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    }
    public List getBeanFactoryPostProcessors() {
        return this.beanFactoryPostProcessors;
    }

这里非常有意思。方法非常简单,但有意思在于:它不是返回Spring容器里面的Processors,而是你自己的注册的(你自己手动set的),也就是说我们自己手动调用set方法添加进去,就能够执行。并不需要自己配置@Bean或者在xml里配置
那么重点就在于PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors,它的代码可谓非常非常多:

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

        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        // 这个doc说明很清楚:不管怎么样,先执行BeanDefinitionRegistryPostProcessors 
        // 需要注意的是BeanDefinitionRegistryPostProcessors 为 BeanFactoryPostProcessor 的子接口 它新增了方法:void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
        // BeanFactoryPostProcessor 的方法为;void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
        // 所以BeanDefinitionRegistryPostProcessors,它可以我们介入,改变Bean的一些定义信息
        Set processedBeans = new HashSet<>();

        // 只有此beanFactory 是BeanDefinitionRegistry  才能执行BeanDefinitionRegistryPostProcessor,才能修改Bean的定义嘛~
        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

            // 此处安放了两个容器,一个装载普通的BeanFactoryPostProcessor
            // 另外一个装载和Bean定义有关的 BeanDefinitionRegistryPostProcessor
            // 另外都是LinkedList,所以执行顺序和set进去的顺序是保持一样的
            List regularPostProcessors = new LinkedList<>();
            List registryProcessors = new LinkedList<>();

            // 这里是我们自己的set进去的,若没set,这里就是空(若是Sprng容器里的,下面会处理,见下面)
            // 从此处可以看出,我们手动set进去的,最最最最有限执行的
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    
                    // 这里执行post方法,然后然后吧它缓冲起来了,放在了registryProcessors里
                    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.
            // 接下来,就是去执行Spring容器里面的一些PostProcessor了。他们顺序doc里也写得很清楚:
            // 先执行实现了PriorityOrdered接口的,然后是Ordered接口的,最后执行剩下的
            List currentRegistryProcessors = new ArrayList<>();

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            // 先从容器中拿出来所有的BeanDefinitionRegistryPostProcessor 然后先执行PriorityOrdered
            // 本例中有一个这个类型的处理器:ConfigurationClassPostProcessor(显然是处理@Configuration这种Bean的)
            // 至于这个Bean是什么时候注册进去的,前面有。在loadBeanDefinitions()初始化AnnotatedBeanDefinitionReader的时候调用的AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)方法的时候,注册了6个Bean
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    
                    // processedBeans也顺带保存了一份,保存的是bean的Name哦~
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            // 排序
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            
            // 此处缓冲起来(需要注意的是,是排序后,再放进去的 这样是最好的)
            registryProcessors.addAll(currentRegistryProcessors);

            // 这个方法很简单,就是吧currentRegistryProcessors里面所有的处理器for循环一个个的执行掉(本处只有ConfigurationClassPostProcessor,详见我的另一篇专门博文讲解)
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 此处把当前持有的执行对象给清空了,需要注意。以方便装载后续执行的处理器们
            currentRegistryProcessors.clear();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            // 此处逻辑完全同上  处理实现Order接口的RegistryProcessors
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                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);
            currentRegistryProcessors.clear();

            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            // 最后执行,两个排序接口都没有实现的BeanDefinitionRegistryPostProcessor们,并且也缓存起来
            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);
                currentRegistryProcessors.clear();
            }

            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            // 现在,这里很明显:去执行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
            // 以及 顶层接口BeanFactoryPostProcessor的postProcessBeanFactory方法
            // 我们当前环境regularPostProcessors长度为0.registryProcessors有一个解析@Configuration的处理器
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        } else {
            // Invoke factory processors registered with the context instance.
            // 若是普通的Bean工厂,就直接执行set进来的后置处理器即可(因为容器里就没有其它Bean定义了)
            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!
        // 下面就是开始执行BeanFactoryPostProcessor 基本也是按照上面的顺序来执行的
        // 上面9个Bean,我们知道 也就ConfigurationClassPostProcessor是实现了此接口的。因此本环境下,只有它了,并且它在上面还已经执行了
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        List priorityOrderedPostProcessors = new ArrayList<>();
        List orderedPostProcessorNames = new ArrayList<>();
        List nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {

            // 这里面注意,已经执行过的后置处理器,就不要再执行了
            if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
            }
            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);
            }
        }

        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

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

        // Finally, invoke all other BeanFactoryPostProcessors.
        List nonOrderedPostProcessors = new ArrayList<>();
        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...
        beanFactory.clearMetadataCache();
    }

postProcessBeanDefinitionRegistry和postProcessBeanFactory方法:
两者都存在于BeanDefinitionRegistryPostProcessor接口中,表明其既可以自定义BeanDefinition并注册进容器中也可以对beanFactory的修改

那为什么逻辑要先执行postProcessBeanDefinitionRegistry然后在执行postProcessBeanFactory呢?

因为postProcessBeanDefinitionRegistry是用来创建bean定义的,而postProcessBeanFactory是修改BeanFactory,当然postProcessBeanFactory也可以修改bean定义的。为了保证在修改之前所有的bean定义的都存在,所以优先执行postProcessBeanDefinitionRegistry。如不是以上顺序,会出先再修改某个bean定义的报错,因为此bean定义的还没有被创建。

至此,invokeBeanFactoryPostProcessors(beanFactory)这一步就完成了。这一步主要做了:

执行了BeanDefinitionRegistryPostProcessor(此处只有ConfigurationClassPostProcessor)
执行了BeanFactoryPostProcessor
完成了@Configuration配置文件的解析,并且把扫描到的、配置的Bean定义信息都加载进容器里
Full模式下,完成了对@Configuration配置文件的加强,使得管理Bean依赖关系更加的方便了

上面5个步骤,已经Bean工厂完全准备好了,并且也注册好了所有的Bean的定义信息(此时Bean还并没有创建)

第六步 registerBeanPostProcessors(beanFactory)

beanPostProcessors的作用就是在bean的初始化前后进行一些操作

这个方法就是从Spring容器中找出的BeanPostProcessor接口的bean(其中还有一个排序问题),并设置到BeanFactory的属性中。之后bean被实例化的时候会调用这个BeanPostProcessor。

该方法委托给了PostProcessorRegistrationDelegate类的registerBeanPostProcessors方法执行。这里的过程跟invokeBeanFactoryPostProcessors类似:

  • 先找出实现了PriorityOrdered接口的BeanPostProcessor并排序后加到BeanFactory的BeanPostProcessor集合中
  • 找出实现了Ordered接口的BeanPostProcessor并排序后加到BeanFactory的BeanPostProcessor集合中
  • 没有实现PriorityOrdered和Ordered接口的BeanPostProcessor加到BeanFactory的BeanPostProcessor集合中

这些已经存在的BeanPostProcessor在postProcessBeanFactory方法中已经说明,都是由AnnotationConfigUtils的registerAnnotationConfigProcessors方法注册的。这些BeanPostProcessor包括有AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)、RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)、CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。

如果是自定义的BeanPostProcessor,已经被ConfigurationClassPostProcessor(应该是beanFactoryPostProcessor)注册到容器内。

这些BeanPostProcessor会在这个方法内被实例化(这个时候就被实例化)(通过调用BeanFactory的getBean方法,如果没有找到实例化的类,就会去实例化)。

源码

    // 发现它又是委托给PostProcessorRegistrationDelegate 去做的
    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }


    public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        
        // 从所与Bean定义中提取出BeanPostProcessor类型的Bean,显然,最初的6个bean,有三个是BeanPostProcessor:
        // AutowiredAnnotationBeanPostProcessor  RequiredAnnotationBeanPostProcessor  CommonAnnotationBeanPostProcessor
        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.
        // 此处有点意思了,向beanFactory又add了一个BeanPostProcessorChecker,并且此事后总数设置为了getBeanPostProcessorCount和addBeanPostProcessor的总和(+1表示自己)
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        // 此处注意:第一个参数beanPostProcessorTargetCount表示的是处理器的总数,总数(包含两个位置离的,用于后面的校验)
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // Separate between BeanPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        // 同样的 先按优先级,归类了BeanPostProcessor
        List priorityOrderedPostProcessors = new ArrayList<>();
        List internalPostProcessors = new ArrayList<>();
        List orderedPostProcessorNames = new ArrayList<>();
        List nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                // MergedBeanDefinitionPostProcessor则是在合并处理Bean定义的时候的回调。这个东东按我的理解也基本是框架内部使用的,用户不用管
                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 orderedPostProcessors = new ArrayList<>();
        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 nonOrderedPostProcessors = new ArrayList<>();
        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).
        // 最后此处需要注意的是:Spring还给我们注册了一个Bean的后置处理器:ApplicationListenerDetector  它的作用:用来检查所有得ApplicationListener
        // 有的人就想问了:之前不是注册过了吗,怎么这里又注册一次呢?其实上面的doc里面说得很清楚:
        // Re-register重新注册这个后置处理器。把它移动到处理器连条的最后面,最后执行(小技巧是:先remove,然后执行add操作~~~ 自己可以点进addBeanPostProcessor源码可以看到这个小技巧)
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

    // 把类型是BeanPostProcessor的Bean,注册到beanFactory里面去
    private static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List postProcessors) {

        for (BeanPostProcessor postProcessor : postProcessors) {
            beanFactory.addBeanPostProcessor(postProcessor);
        }
    }

第七步 initMessageSource方法

初始化MessageSource组件(做国际化功能;消息绑定,消息解析),这个接口提供了消息处理功能。主要用于国际化
初始化消息源。向容器里注册一个一个事件源的单例Bean:MessageSource

    protected void initMessageSource() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();

        // 判断是否已经存在名为“messageSource”的Bean了(一般情况下,我们都是没有的)
        if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
            // 从容器里拿出这个messageSource 
            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());
                }
            }
        }
        else {
            // Use empty MessageSource to be able to accept getMessage calls.
            DelegatingMessageSource dms = new DelegatingMessageSource();

            // 其实就是获取到父容器的messageSource字段(否则就是getParent()上下文自己)
            dms.setParentMessageSource(getInternalParentMessageSource());
            // 给当前的messageSource赋值
            this.messageSource = dms;
            // 把messageSource作为一个单例的Bean注册进beanFactory工厂里面
            beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
        }
    }

refresh() 第八步:initApplicationEventMulticaster()

在Spring容器中初始化事件广播器,事件广播器用于事件的发布。
程序首先会检查bean工厂中是否有bean的名字和这个常量(applicationEventMulticaster)相同的,如果没有则说明没有那么就使用默认的ApplicationEventMulticaster 的实现:SimpleApplicationEventMulticaster

这个逻辑太简单了,一句话:若用户自己定义了这个Bean(备注:Bean名称必须是"applicationEventMulticaster"哦),就以用户的为准。否则注册一个系统默认的

    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);
        } else {
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); 
        }
    }

第九步:onRefresh()

一个模板方法,不同的Spring容器做不同的事情。

    @Override
    protected void onRefresh() {
        this.themeSource = UiApplicationContextUtils.initThemeSource(this);
    }

第十步 registerListeners();

上面我们已经把事件源、多播器都注册好了,这里就是注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean,这些监听器是注册到ApplicationEventMulticaster中的。这不会影响到其它监听器bean。在注册完以后,还会将其前期的事件发布给相匹配的监听器。

    protected void registerListeners() {
        // 这一步和手动注册BeanDefinitionRegistryPostProcessor一样,可以自己通过set手动注册监听器  然后是最新执行的(显然此处我们无自己set)
        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!
        // 取到容器里面的所有的监听器的名称,绑定到广播器  后面会广播出去这些事件的
        // 同时提醒大伙注意:此处并没有说到ApplicationListenerDetector这个东东,下文会分解
        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...
        // 这一步需要注意了:如果存在早期应用事件,这里就直接发布了(同时就把earlyApplicationEvents该字段置为null)
        // 
        Set earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }

第十一步 finishBeanFactoryInitialization(beanFactory)

实例化(使用getBean的方式)BeanFactory中已经被注册但是未实例化的所有实例(懒加载的不需要实例化)。

比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化。

实例化的过程各种BeanPostProcessor开始起作用。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // Initialize conversion service for this context.
        // 初始化上下文的转换服务,ConversionService是一个类型转换接口
        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.
        // 设置一个内置的值处理器(若没有的话),该处理器作用有点像一个PropertyPlaceholderConfigurer bean
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }

        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
        // 注意此处已经调用了getBean方法,初始化LoadTimeWeaverAware Bean
        // getBean()方法的详细,下面会详细分解
        // LoadTimeWeaverAware是类加载时织入的意思
        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 definition数据,不期望以后会改变
        beanFactory.freezeConfiguration();

        // Instantiate all remaining (non-lazy-init) singletons.
        // 这个就是最重要的方法:会把留下来的Bean们  不是lazy懒加载的bean都实例化掉
        //  bean真正实例化的时刻到了
        beanFactory.preInstantiateSingletons();
    }


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

接下来重点看看DefaultListableBeanFactory#preInstantiateSingletons:实例化所有剩余的单例Bean

    @Override
    public void preInstantiateSingletons() throws BeansException {

        // 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...
        for (String beanName : beanNames) {
            //getMergedLocalBeanDefinition:见下~
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    
            // 不是抽象类&&是单例&&不是懒加载
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {

                // 这是Spring提供的对工程bean模式的支持:比如第三方框架的继承经常采用这种方式
                // 如果是工厂Bean,那就会此工厂Bean放进去
                if (isFactoryBean(beanName)) {
                    // 拿到工厂Bean本省,注意有前缀为:FACTORY_BEAN_PREFIX 
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean factory = (FactoryBean) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction)
                                            ((SmartFactoryBean) factory)::isEagerInit,
                                    getAccessControlContext());
                        } else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean) factory).isEagerInit());
                        }

                        // true:表示渴望马上被初始化的,那就拿上执行初始化~
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                } else { // 这里,就是普通单例Bean正式初始化了~  核心逻辑在方法:doGetBean 
                    // 关于doGetBean方法的详解:下面有贴出博文,专文讲解
                    getBean(beanName);
                }
            }
        }

        // Trigger post-initialization callback for all applicable beans...
        // SmartInitializingSingleton:所有非lazy单例Bean实例化完成后的回调方法 Spring4.1才提供
        //SmartInitializingSingleton的afterSingletonsInstantiated方法是在所有单例bean都已经被创建后执行的
        //InitializingBean#afterPropertiesSet 是在仅仅自己被创建好了执行的
        // 比如EventListenerMethodProcessor它在afterSingletonsInstantiated方法里就去处理所有的Bean的方法
        // 看看哪些被标注了@EventListener注解,提取处理也作为一个Listener放到容器addApplicationListener里面去
        for (String beanName : beanNames) {
            Object singletonInstance = getSingleton(beanName);

            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedAction) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                }
                else {
                    // 比如:ScheduledAnnotationBeanPostProcessor CacheAspectSupport  MBeanExporter等等
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }
 
 

此处必须说明:此处绝大部分的单例Bean定义信息都会被实例化,但是如果是通过FactoryBeab定义的,它是懒加载的(如果没人使用,就先不会实例化。只会到使用的时候才实例化~)。如下例子:

第十二步 finishRefresh()

refresh做完之后需要做的其他事情。

  • 初始化生命周期处理器,并设置到Spring容器中(LifecycleProcessor)
  • 调用生命周期处理器的onRefresh方法,这个方法会找出Spring容器中实现了SmartLifecycle接口的类并进行start方法的调用
  • 发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
    protected void finishRefresh() {
        // Clear context-level resource caches (such as ASM metadata from scanning).
        // 这个是Spring5.0之后才有的方法
        // 表示清除一些resourceCaches,如doc说的  清楚context级别的资源缓存,比如ASM的元数据
        clearResourceCaches();

        // Initialize lifecycle processor for this context.
        // 初始化所有的LifecycleProcessor  详见下面
        initLifecycleProcessor();

        // Propagate refresh to lifecycle processor first.
        // 上面注册好的处理器,这里就拿出来,调用它的onRefresh方法了
        getLifecycleProcessor().onRefresh();

        // Publish the final event.
        // 发布容器刷新的事件:
        publishEvent(new ContextRefreshedEvent(this));

        // Participate in LiveBeansView MBean, if active.
        // 和MBeanServer和MBean有关的。相当于把当前容器上下文,注册到MBeanServer里面去。
        // 这样子,MBeanServer持久了容器的引用,就可以拿到容器的所有内容了,也就让Spring支持到了MBean的相关功能
        LiveBeansView.registerApplicationContext(this);
    }

initLifecycleProcessor()方法(生命周期
在 Spring 中还提供了 Lifecycle 接口, Lifecycle 中包含start/stop方法,实现此接口后Spring会保证在启动的时候调用其start方法开始生命周期,并在Spring关闭的时候调用 stop方法来结束生命周期
当ApplicationContext启动或停止时,它会通过LifecycleProcessor来与所有声明的bean的周期做状态更新,而在LifecycleProcessor的使用前首先需要初始化。

// 这个初始化逻辑比较简单
    protected void initLifecycleProcessor() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    
        // 如果工厂里已经存在LifecycleProcessor,那就拿出来,把值放上去this.lifecycleProcessor
        if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
            this.lifecycleProcessor = beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
        }
        // 一般情况下,都会注册上这个默认的处理器DefaultLifecycleProcessor
        else {
            DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
            defaultProcessor.setBeanFactory(beanFactory);
            this.lifecycleProcessor = defaultProcessor;
            // 直接注册成单例Bean进去容器里
            beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
        }
    }

getLifecycleProcessor().onRefresh()

Spring的IoC容器启动过程中,默认只会执行实现了SmartLifecycle接口且isAutoStartup()=true的Bean的start()方法的。(所以你要想容器启动后就执行,请实现SmartLifecycle吧)

至此,Spring IOC容器正式启动成功了。

额外话题, 如何优雅关闭spring容器

Runtime.getRuntime().addShutdownHook(shutdownHook)

Runtime.addShutdownHook(Thread hook)向JVM添加关闭钩子。

Spring容器的refresh()【创建、刷新】完整总结

1、prepareRefresh()刷新前的预处理;
    0)、this.closed.set(false),this.active.set(true)  设置一些标记位
    1)、initPropertySources()初始化一些属性设置;(交由子类去实现,比如web容器中的 AbstractRefreshableWebApplicationContext 就去初始化了servlet的一些init参数等等)
    2)、getEnvironment().validateRequiredProperties();检验属性的合法等
    3)、earlyApplicationEvents= new LinkedHashSet();初始化容器,保存一些早期的事件;
    
2、obtainFreshBeanFactory();获取BeanFactory;
    1)、refreshBeanFactory();抽象方法,子类【AbstractRefreshableApplicationContext】唯一实现的:
            ①、若已经存在beanFactory了,那就做一些清理工作(销毁单例Bean、关闭工厂)
            ②、创建了一个this.beanFactory = new DefaultListableBeanFactory();并且设置id
            ③、把旧的工厂的属性赋值给新创建的工厂:customizeBeanFactory(beanFactory)
            ④、loadBeanDefinitions(beanFactory):加载Bean定义。抽象方法,由子类去决定从哪儿去把Bean定义加载进来,实现有比如:
                    XmlWebApplicationContext:专为web设计的从xml文件里加载Bean定义(借助XmlBeanDefinitionReader)
                    ClassPathXmlApplicationContext/FileSystemXmlApplicationContext:均由父类AbstractXmlApplicationContext去实现这个方法的,也是借助XmlBeanDefinitionReader
                    AnnotationConfigWebApplicationContext:基于注解驱动的容器。(也是当下最流行、最重要的一个实现,前面一篇博文对此有重点分析),借助了AnnotatedBeanDefinitionReader.register()方法加载Bean定义
                        (这里面需要注意的是:.register()只是把当前这一个Class对象registry.registerBeanDefinition()了,至于内部的@Bean、@ComponentScan扫描到的,都不是在此处注册的)
                        
                    有必要说一句:AnnotationConfigApplicationContext是在非web环境下的容器。它虽然没有实现实现loadBeanDefinitions()抽象方法,是因为它在new对象的时候,已经调用了.register()完成配置Bean定义信息的注册了
    2)、getBeanFactory();返回刚才GenericApplicationContext创建的BeanFactory对象;
    3)、将创建的BeanFactory【DefaultListableBeanFactory】返回;
    =======到这一步截止,BeanFactory已经创建好了(只不过都还是默认配置而已),配置Bean的定义信息也注册好了=======
    
3、prepareBeanFactory(beanFactory);BeanFactory的预准备工作(对BeanFactory进行一些设置);
    1)、设置BeanFactory的类加载器、StandardBeanExpressionResolver、ResourceEditorRegistrar
    2)、添加感知后置处理器BeanPostProcessor【ApplicationContextAwareProcessor】,并设置一些忽略EnvironmentAware、EmbeddedValueResolverAware、xxxxx(因为这个处理器都一把抓了)
    3)、注册【可以解析的(表示虽然不在容器里,但还是可以直接 @Auwowired)】自动装配;我们能直接在任何组件中自动注入(@Autowired):
            BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
    5)、添加BeanPostProcessor【ApplicationListenerDetector】 检测注入进来的Bean是否是监听器
    6)、Detect a LoadTimeWeaver and prepare for weaving, if found.添加编译时的AspectJ支持:LoadTimeWeaverAwareProcessor
        (添加的支持的条件是:beanFactory.containsBean("loadTimeWeaver"))
    7)、给BeanFactory中注册一些能用的组件;
        environment-->【ConfigurableEnvironment】、
        systemProperties-->【Map】、
        systemEnvironment-->【Map】

4、postProcessBeanFactory(beanFactory);BeanFactory准备工作完成后进行的后置处理工作;(由子类完成)
    一般web容器都会对应的实现此方法,比如 AbstractRefreshableWebApplicationContext:
        1)、添加感知BeanPostProcessor【ServletContextAwareProcessor】,支持到了ServletContextAware、ServletConfigAware
        2)、注册scopse:beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());当然还有SCOPE_SESSION、SCOPE_APPLICATION
        3)、向上线一样,注册【可以解析的】自动注入依赖:ServletRequest/ServletResponse/HttpSession/WebRequest
            (备注:此处放进容器的都是xxxObjectFactory类型,所以这是为何@Autowired没有线程安全问题的重要一步)
        4)、registerEnvironmentBeans:注册环境相关的Bean(使用的registerSingleton,是直接以单例Bean放到容器里面了)
            servletContext-->【ServletContext】
            servletConfig-->【ServletConfig】
            contextParameters-->【Map】 保存有所有的init初始化参数(getInitParameter)
            contextAttributes-->【Map】 servletContext的所有属性(ServletContext#getAttribute(String))
            
========以上是BeanFactory的创建及预准备工作,至此准备工作完成了,那么接下来就得利用工厂干点正事了========

5、invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessor的方法;
    BeanFactoryPostProcessor:BeanFactory的后置处理器。此处调用,现在就表示在BeanFactory标准初始化之后执行的;
    两个接口:BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor(子接口)
    1)、执行BeanFactoryPostProcessor们的方法;
    
        ===先执行BeanDefinitionRegistryPostProcessor===
        1)、获取所有的BeanDefinitionRegistryPostProcessor;(当然会最先执行我们手动set进去的Processor,但是这个一般都不会有)
        2)、先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor、
            postProcessor.postProcessBeanDefinitionRegistry(registry)
        3)、在执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor
        4)、最后执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessors
        (小细节:都会调用getBean(“name”,BeanDefinitionRegistryPostProcessor.class)方法,所以都会先实例化,才去执行的)
        
        **这里面需要特别的介绍一个处理器:`ConfigurationClassPostProcessor`,它是一个BeanDefinitionRegistryPostProcessor**
        **它会解析完成所有的@Configuration配置类,然后所有@Bean、@ComponentScan等等Bean定义都会搜集进来了,所以这一步是非常的重要的**
    
        ===再执行BeanFactoryPostProcessor的方法(顺序逻辑同上,略)===
    2)、再次检测一次添加对AspectJ的支持。为何还要检测呢?through an @Bean method registered by ConfigurationClassPostProcessor,这样我们注入了一个切面Bean,就符合条件了嘛
        
6、registerBeanPostProcessors(beanFactory);注册BeanPostProcessor(Bean的后置处理器)【 intercept bean creation】
        **不同接口类型的BeanPostProcessor;在Bean创建前后的执行时机是不一样的**
        BeanPostProcessor:BeanPostProcessor是一个工厂钩子,允许Spring框架在新创建Bean实例时对其进行定制化修改,比如填充Bean、创建代理、解析Bean内部的注解等等。。。
        DestructionAwareBeanPostProcessor:Bean销毁时候
        InstantiationAwareBeanPostProcessor:Bean初始化的时候
        SmartInstantiationAwareBeanPostProcessor:初始化增强版本:增加了一个对Bean类型预测的回调(一般是Spring内部使用,调用者还是使用InstantiationAwareBeanPostProcessor就好)
        MergedBeanDefinitionPostProcessor:合并处理Bean定义的时候的回调【该类型的处理器保存在名为internalPostProcessors的List中】、
        
        1)、获取所有的 BeanPostProcessor;后置处理器都默认可以通过PriorityOrdered、Ordered接口来执行优先级
        2)、先注册PriorityOrdered优先级接口的BeanPostProcessor;
            把每一个BeanPostProcessor;添加到BeanFactory中
            beanFactory.addBeanPostProcessor(postProcessor);
        3)、再注册Ordered接口的、最后注册没有实现任何优先级接口的、最终注册MergedBeanDefinitionPostProcessor
            (此处细节:BeanPostProcessor本身也是一个Bean,其注册之前一定先实例化,而且是分批实例化和注册。
            另外还有一个非常非常重要的一点就是阶段顺序问题:
            我们可以把BeanPostProcessor的实例化与注册分为四个阶段:
                    第一阶段applicationContext内置阶段、
                    第二阶段priorityOrdered阶段、
                    第三阶段Ordered阶段、
                    第四阶段nonOrdered阶段
            因为是分批注册,所以我们同阶段是不能拦截到同阶段的BeanPostProcessor的实例化的。举例子:
            PriorityOrdered的只能被内置阶段的比如:ApplicationContextAwareProcessor(可以注入啦)/ApplicationListenerDetector(可以接受事件啦)这种拦截
            而:Ordered就可以被   内置的、PriorityOrdered都拦截到了
            。。。 以此类推。。。
            
            所以我们的BeanPostProcessor是可以@Autowired 比如Service、Dao来做一些事的。单思,但是一定要【注意避免BeanPostProcessor启动时的“误伤”陷阱】,什么意思?大概解释一下如下:
                可能由于你的Processor依赖于某个@Bean,从而让它提前实例化了,然后就很可能错过了后面一些BeanPostProcessor的处理,造成“误伤”
                (SpringBoot中使用Shiro、Spring-Cache的时候,使用不当会出现这样的问题)
    
        6)、这一步非常有意思:moving it to the end of the processor chain。它的又注册了一次,作用是把这个探测器移动到处理器的底部,最后一个(显然,最后一个是为了不要放过任何Bean)
            (小细节:可能有小伙伴疑问,这里也是new出来,这这样容器内不就有两个探测器对象了吗?气其实不然,ApplicationListenerDetector它重写了hashCode方法,且只和应用applicationContext有关)
            return ObjectUtils.nullSafeHashCode(this.applicationContext);所以对它执行remove的时候,会被当作同一个对象处理,能把老的移除成功添加新的的

7、initMessageSource();初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
        1)、看容器中是否有id为messageSource的,类型是MessageSource的组件
            如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource;
                MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取;
        2)、把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSource
        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource)
        
8、initApplicationEventMulticaster();初始化事件派发器;
        1)、从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster;
        2)、如果上一步没有配置;创建一个SimpleApplicationEventMulticaster,将创建的ApplicationEventMulticaster添加到BeanFactory中
        
9、onRefresh();留给子容器(子类) 容器刷新的时候做些事
        AbstractRefreshableWebApplicationContext:this.themeSource = UiApplicationContextUtils.initThemeSource(this);
        
10、registerListeners();把容器中将所有项目里面的ApplicationListener注册进来;
        1、拿到容器里所有的Bean定义的名字,类型为ApplicationListener,然后添加进来
            getApplicationEventMulticaster().addApplicationListener(listener);
        2、派发之前步骤产生的事件(早期事件)
        (细节:此处只是把Bean的名字放进去,Bean还没有实例化哦~~~~)

11、finishBeanFactoryInitialization(beanFactory);初始化所有剩下的单实例bean;这应该是最核心的一步了
    1)、为容器初始化ConversionService(容器若没有就不用初始化了,依然采用getBean()初始化的) 提供转换服务
    2)、若没有设置值解析器,那就注册一个默认的值解析器(lambda表示的匿名处理)
    3)、实例化LoadTimeWeaverAware(若存在)
    4)、清空临时类加载器:beanFactory.setTempClassLoader(null)
    5)、缓存(快照)下当前所有的Bean定义信息 beanFactory.freezeConfiguration();
    ==== 更精确的是说是根据Bean的定义信息:beanDefinitionNames来实例化、初始化剩余的Bean ====
    6)、beanFactory.preInstantiateSingletons();初始化后剩下的单实例bean(过程这里就不详说了)
    
12、finishRefresh();完成BeanFactory的初始化创建工作;IOC容器就创建完成
        0)、clearResourceCaches(); (Spring5.0才有)
        1)、initLifecycleProcessor();初始化和生命周期有关的后置处理器;从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有new DefaultLifecycleProcessor();
            关于Lifecycle接口的使用,也专门讲解过,这里不聊了
        2)、getLifecycleProcessor().onRefresh();  相当于上面刚注册,下面就调用了
        3)、publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件;
        4)、liveBeansView.registerApplicationContext(this); 和MBean相关,略
    
    ======总结===========
    1)、Spring容器在启动的时候,先会保存所有注册进来的Bean的定义信息(可以有N种方式);
        1)、xml注册bean;
        2)、注解注册Bean;@Service、@Component、@Bean、xxx
    2)、Spring容器会合适的时机创建这些Bean
        1)、用到这个bean的时候;利用getBean创建bean;创建好以后保存在容器中;
        2)、统一创建剩下所有的bean的时候;finishBeanFactoryInitialization();
    3)、后置处理器;BeanPostProcessor
        1)、每一个bean创建完成,都会使用各种后置处理器进行处理;来增强bean的功能;
            AutowiredAnnotationBeanPostProcessor:处理自动注入
            AnnotationAwareAspectJAutoProxyCreator:来做AOP功能;
            xxx....
            增强的功能注解:
            AsyncAnnotationBeanPostProcessor
            ....
    4)、事件驱动模型;
        ApplicationListener;事件监听;
        ApplicationEventMulticaster;事件派发:

个人感悟

  • 感觉spring的整个启动过程, 留了很多很多的扩展点
    比如各种postProcessor, 比如各种接口 aware, lifeCycileProcessor, 比如模板方法之类的
  • 里面很多东西都注重一个加载顺序
  • 有一些bean可能一开始就直接注册好了
  • beanDefinition的获取在2个阶段, 一个是创建工厂读取配置阶段, 一个是 第一个BeanFactoryProcessor(ConfigurationProcessor会扫描所有注解)

参考博客:

  • https://www.cnblogs.com/grasp/p/11942735.html
  • https://cloud.tencent.com/developer/article/1497793

你可能感兴趣的:(spring中的refresh函数)