springIOC的refresh方法

_

refresh方法概览

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
} catch (BeansException 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();
}
}
}

refresh方法步骤说明

prepareRefresh

主要是做一些初始化的工作.验证必要属性. 初始化earlyApplicationListeners

obtainFreshBeanFactory

创建并获取 BeanFactory (是否可以重复调用refresh区分两种子类实现)

AbstractRefreshableApplicationContext

主要是xml的实现

  1. FileSystemXmlApplicationContext
  2. ClassPathXmlApplicationContext

GenericApplicationContext

通用的实现

  1. GenericXmlApplicationContext
  2. StaticApplicationContext
  3. GenericGroovyApplicationContext
  4. AnnotationConfigApplicationContext

prepareBeanFactory

BeanFactory做一些默认的初始化工作(,)

  1. 设置classloader
  2. 基于ApplicationContext的一系列Aware接口的BeanPostProcessor
  3. 注册ApplicationListener接口的BeanPostProcessor
  4. 注册默认的Bean (Environment等)

postProcessBeanFactory

默认为空,由子类去实现

在SpringMVC 中

  1. 注册ServeletContextAware
  2. 注册RequestSession,ApplicationScope
  3. 注册RequestObjectFactory/ResponseObjectFactory/SessionObjectFactory/WebRequestObjectFactory 等工厂Bean,用来处理在Controller 中使用成员变量的方式注入Request/Response/Session/WebRequest等对象。具体使用可见下面
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @RequestMapping
    @Controller
    public class TestController{
    // 这里注入的对象是其实是一个代理了RequestObjectFactory的代理对象
    // 在每次调用时都会使用RequestContextHolder从当前上下文中获取HttpServletRequest对象来进行真实的调用
    @Autowired
    private HttpServletRequest httpRequest;
    @GetMapping("test")
    public String handle(){
    HttpSession session = httpRequest.getSession();
    }
    }

invokeBeanFactoryPostProcessors

顾名思义 就是调用BeanFactoryPostProcessorpostProcessBeanFactory方法

会优先执行实现了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

  1. 初始化ConversionService
  2. 增加默认的StringValueResolver用来解析注解value中的${}占位符.例如@PathVariable("${name}")
  3. 初始化其他所有非Lazy的Bean (Bean的初始化)

finishRefresh

  1. 初始化LifecycleProcessor并调用LifecycleProcessor.onRefresh()
  2. 发布ContextRefreshedEvent事件

其他

关于ApplicationEvent

在spring中有四个ApplicationEvent的子类(对应发出事件的方法)

  1. ContextRefreshedEvent -> refresh()
  2. ContextClosedEvent -> close()
  3. ContextStartedEvent -> start()
  4. ContextStoppedEvent -> stop()

我们在启动/销毁spring容器是调用ApplicationContextrefresh/close方法(对于spring容器启动/关闭,这两个方法就够了)

但是为什么还要设计start/stop 两个事件呢? 而且spring默认启动时也不会调用对应的方法去触发这两个事件(除非手动调用ApplicationContext.start())

对于start/stop两个事件。主要还是用于将其他组件的生命周期和Spring的生命周期做绑定(使用SmartLifecycle接口,Lifecycle接口只有在调用ApplicationContext.start/stop方法之后才会执行)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface SmartLifecycle extends Lifecycle, Phased {
// 是否在spring启动时自动启动
default boolean isAutoStartup() {
return true;
}

default void stop(Runnable callback) {
stop();
callback.run();
}
// 启动的阶段,类似order 数字越小越先执行
default int getPhase() {
return DEFAULT_PHASE;
}

}