refresh这个方法就是帮助我们初始化spring容器的。具体帮助我们初始化了哪些功能,这个我们就需要看源码了。我们可以找到ApplicationContext的基础实现,AbstractApplicationContext中的refresh方法。我们可以分为大致12个大步骤。



我们来如何梳理这12个步骤到底是在干什么呢,这是个问题。我觉得 我们首先可以宏观的先知道这12个步骤在做什么,我们可以理解这12个步骤都是在为applicationContext容器添加功能。更细说就是给applicationcontext中的成员变量赋值。包括Environment,MessageSource,lifecycleProcessor,ApplicationEventMuiticaster,BeanFactory。这十二个步骤就是对这五个对象进行初始化操作。接下来我们来划分哪些步骤是对应哪一个对象的初始化。

Environment(1)
我们首先来看Environment,第一步就是初始化Environment。Environment可能有很多同学不知道是什么,我们这里简单说下,Environment中存储的是一个一个键值信息。包括系统属性,系统变量,还有我们自定义的properties。自定义的比如最常见的application.properties文件。我们下面简单演示演示。可以看见成功打印出了java_home的值。

这里可能有同学会问为什么用的是StandardEnvironment这个类。我们可以看类图关系,该类实现了Environment接口。可能又会有疑问,Environment接口不会只有一个实现类,怎么用这个实现类。至于为什么因为,spring默认就是用的这个实现类,什么?不信。那就看看源码。

我们先进入第一步中,找到getEnvironment方法,再进去,再进去就成功找到了,实现类确实是StandardEnvironment。



MessageSource(7)
这个对象呢,是在第7步,initMessageSource()。 该对象的作用就是实现国际化的,平时也很少接触,也不深讲。就知道是这个功能就行了。代码逻辑大致就是在在容器中找一个name为messageSource的实现类,如果没有就默认提供空实现。
lifeCycleProcessor(12)
这个就是生命周期处理器,它的作用就是用来控制容器中需要生命周期管理的bean,调用context.start就会调用所有实现了lifeCycle接口的start,stop方法也是一样的。
applicationEventMuilticaster(8,10)
这个对象呢是在第8步进行创建的,但为什么还有个第10步呢,第十步就是对该对象中的属性进行完善。
我们首先说下该功能,功能就是发布事件,事件发布器。我们来看下第8步的源码。这个源码还是不难,这里只是个简单的if-else判断,我大致说一下过程,首先会判断容器中是否有一个name为applicationEventMulticatser的bean。(这里并不是真正的bean对象哦,这里知识判断beanDefinitionMap中是否有该BeanDefinition。)如果有,就把该对象给applicationContext。如果没有就默认用SimpleApplicationEvnetMuticaster实现类。

接下来就是第10步,第8步是用来发布事件,那么第10步就是用来接收事件的,监听器。通过源码可以知道,首先会将实现了ApplicationListener接口的实现类的name全部拿出来,然后放进ApplicationEventMulticaster下的defaultRetriever下的set集合保存。以后当发布器发布事件时,就会遍历该集合进行接收。




注意:监听器不只只能实现ApplicationListener接口,还可以通过加@EventListener注解来实现。
BeanFactory(2,3,4,5,6,11)
BeanFactory就是重量级的了,他是核心功能的重要实现。比如依赖注入,对象的实例化,对象的存储都是该对象完成的。这里可能就有疑惑了,明明applicationContext继承了BeanFactory接口,为什么还要内置一个BeanFactory。这里做一个解释,我们要分清楚BeanFactory接口和他的实现类,BeanFactory本身的功能十分有限。所以我们在ApplicationContext中创建的是BeanFactory其中最重要的一个实现类DefaultListableBeanFactory。该实现类的功能就非常强大了。所以这也是为什么既要继承BeanFactory接口还要内置一个BeanFactory。
第2步
我们首先来看第2步,第2步就是创建DefaultListableBeanFactory,并通过BeanDefinition源,找到BeanDefinition,并注册到BeanDefinitionMap中,name就是key,BeanDefinition就是value。BeanDefinition源有哪些呢,主要有xml,配置类,还有扫描获取。具体操作就不演示了。
第3步
第3步就是初始化一些不那么重要的。但也需要,不是重点,简单说说。主要就是以下这四个。我们就简单说说其每个的作用
- beanExpressionResolver:用来解析spel表达式
- propertyEditorRegistrars:类型转换器,比如值注入时,会将string类型转化为其他的类型
- resolvableDependencies:用来装特殊的Bean的,比如ApplicationContext,BeanFactory。
- beanPostprocessors:bean后置处理器,这个就不多说了。这里默认注册的bean后置处理器作用也不是很大。

第4步
第4步可以看到是个空实现,其实现由具体的子类对其进行扩展,比如web环境下对scope进行扩展,我们知道web环境下scope还需要由request,session,application三个域。而非web下就不需要。
这里体现了设计模式的模板方法,大致的流程由父类规定死了,其中可以扩展的方法父类留空了,其子类可以对其进行扩展
第5步
第五步就是初始化一些BeanFactoryPostProcessor,bean工厂后置处理器。这个我也不多说,什么是bean工厂后置处理器,及其作用是什么,前面章节都有讲。
第6步
第6步是扩展一些BeanPostProcessor,在第三步时就已经添加了一些功能不强大的Bean后置处理器,这一步会添加功能更强大的Bean后置处理器。具体也不讲,太累了。啊~。
第11步
第11步也就是最重要的一步,就是真正对单例对象进行创建,并放进singletonObjects中。在创建单例对象前还有俩步骤。
conversionService:也是一套转换机制,是对propertyEditorRegistrars的补充
embeddedValueResolvers:用来解析${}表达式的解析器

第9步onrefresh()方法
该方法同样是也是空实现,也同样是模板方法,和第四步如出一辙。由子类具体来实现功能。比如web环境下,就会通过该方法,实现内置tomcat的创建。
经过以上的总结想必大家更容易理解了吧。
