springIOC的refresh方法
_
refresh方法概览
1 | public void refresh() throws BeansException, IllegalStateException { |
refresh方法步骤说明
prepareRefresh
主要是做一些初始化的工作.验证必要属性. 初始化earlyApplicationListeners
obtainFreshBeanFactory
创建并获取 BeanFactory (是否可以重复调用refresh区分两种子类实现)
AbstractRefreshableApplicationContext
主要是xml的实现
- FileSystemXmlApplicationContext
- ClassPathXmlApplicationContext
GenericApplicationContext
通用的实现
- GenericXmlApplicationContext
- StaticApplicationContext
- GenericGroovyApplicationContext
- AnnotationConfigApplicationContext
prepareBeanFactory
对BeanFactory
做一些默认的初始化工作(,)
- 设置classloader
- 基于
ApplicationContext
的一系列Aware接口的BeanPostProcessor
- 注册
ApplicationListener
接口的BeanPostProcessor
- 注册默认的Bean (Environment等)
postProcessBeanFactory
默认为空,由子类去实现
在SpringMVC 中
- 注册
ServeletContextAware
- 注册
Request
,Session
,Application
的Scope
- 注册
RequestObjectFactory
/ResponseObjectFactory
/SessionObjectFactory
/WebRequestObjectFactory
等工厂Bean,用来处理在Controller
中使用成员变量的方式注入Request
/Response
/Session
/WebRequest
等对象。具体使用可见下面1
2
3
4
5
6
7
8
9
10
11
12
public class TestController{
// 这里注入的对象是其实是一个代理了RequestObjectFactory的代理对象
// 在每次调用时都会使用RequestContextHolder从当前上下文中获取HttpServletRequest对象来进行真实的调用
private HttpServletRequest httpRequest;
public String handle(){
HttpSession session = httpRequest.getSession();
}
}
invokeBeanFactoryPostProcessors
顾名思义 就是调用BeanFactoryPostProcessor
的postProcessBeanFactory
方法
会优先执行实现了
PriorityOrdered
接口的,然后在执行实现了Ordered
接口的,最后再执行其他的BeanFactoryPostProcessor
registerBeanPostProcessors
同样看名字就能知道是注册BeanPostProcessor
同样也遵循
实现了PriorityOrdered
->实现了Ordered
->其他BeanPostProcessor
initMessageSource
一样,做MessageSource
Bean的初始化
initApplicationEventMulticaster
初始化ApplicationEventMulticaster
用来支持 ApplicationListener/ApplicationEvent 事件订阅与发布
onRefresh
空实现,在SpringMVC中用来初始化 ThemeSource
registerListeners
这一步自然就是把ApplicationListener
注册到上面的ApplicationEventMulticaster
中
并不会初始化
ApplicationListener
对象,只是添加BeanName。为了能应用BeanPostProcessor
初始化都在下一步去做
finishBeanFactoryInitialization
- 初始化
ConversionService
- 增加默认的
StringValueResolver
用来解析注解value中的${}
占位符.例如@PathVariable("${name}")
- 初始化其他所有非Lazy的Bean (Bean的初始化)
finishRefresh
- 初始化
LifecycleProcessor
并调用LifecycleProcessor.onRefresh()
- 发布
ContextRefreshedEvent
事件
其他
关于ApplicationEvent
在spring中有四个ApplicationEvent
的子类(对应发出事件的方法)
- ContextRefreshedEvent -> refresh()
- ContextClosedEvent -> close()
- ContextStartedEvent -> start()
- ContextStoppedEvent -> stop()
我们在启动/销毁spring容器是调用ApplicationContext
的 refresh
/close
方法(对于spring容器启动/关闭,这两个方法就够了)
但是为什么还要设计start/stop 两个事件呢? 而且spring默认启动时也不会调用对应的方法去触发这两个事件(除非手动调用ApplicationContext.start())
对于start
/stop
两个事件。主要还是用于将其他组件的生命周期和Spring的生命周期做绑定(使用SmartLifecycle
接口,Lifecycle
接口只有在调用ApplicationContext.start/stop
方法之后才会执行)
1 | public interface SmartLifecycle extends Lifecycle, Phased { |