初始化12步驟
容器建立會進入 refresh 方法,總共 12 個步驟
// org.springframework.context.support.AbstractApplicationContext#refresh
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 步驟一:準備階段
prepareRefresh();
// 步驟二:獲得一個 BeanFactory(bean 定義資訊在這一步會儲存好)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 步驟三:給 BeanFactory 賦能
prepareBeanFactory(beanFactory);
try {
// 步驟四:擴充套件 BeanFactory(這是個鉤子方法,目的是留給子類的,子類可根據需要再次賦予 BeanFactory 更多能力)
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 步驟五:執行 BeanFactoryProPercessor
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();
}
...
}
}
步驟1:準備容器
// org.springframework.context.support.AbstractApplicationContext#prepareRefresh
protected void prepareRefresh() {
// 計時
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// 這是一個模板方法,子類複寫自定義配置 spring 資訊,MVC、Boot、Cloud 等很多框架都複寫過
initPropertySources();
// 必要引數驗證
getEnvironment().validateRequiredProperties();
// 初始化事件監聽器和事件,都置為空列表
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
this.earlyApplicationEvents = new LinkedHashSet<>();
}
步驟2:獲得 BeanFactory
- 產生一個新鮮的 BeanFactory
- 儲存好 bean 定義資訊
ApplicationContext 一般叫容器,BeanFactory 是真正儲存 bean 的地方
// org.springframework.context.support.AbstractApplicationContext#obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
// org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
// 這裡會把 bean 定義資訊準備好
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
步驟3:初始化 BeanFactory
上一步剛初始化了 BeanFactory,還沒什麼能力,這一步是配置 BeanFactory 的屬性,讓其具有處理某些動作的能力
當遇到相關動作,就會使用這裡賦予的能力,所以這裡程式碼比較簡單,就是給不同屬性賦值
- 比如 addBeanPostProcessor 給 BeanFactory 新增了一些後置處理器
- 加入到 beanPostProcessors 屬性中
- 比如 SPEL 解析器,各種 Aware 回撥處理器
- 比如 ignoreDependencyInterface 忽略了一些自動裝配的類
- 加入到 ignoredDependencyInterfaces 屬性中
- 1,這些介面的實現類的屬性@Autowired 不生效(不能注入別的 bean)
- 2,別的 bean 裡也使用 @Autowired 給屬性賦值也不生效(不能被別的 bean 注入)
- 比如 registerResolvableDependency 提前放入一些可能需要別的依賴的 bean
- 是加入到 resolvableDependencies 屬性中
- 這一步是為了提升效率的,如果不提前放,後面找到這些 bean 也會放進去(事先就放進去)
// org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 類載入器
beanFactory.setBeanClassLoader(getClassLoader());
// 是否不解析 SPEL,spring.spel.ignore 配置項來控制
if (!shouldIgnoreSpel) {
// StandardBeanExpressionResolver:SPEL 表示式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
// ResourceEditorRegistrar:用於把配置檔案轉成一個 Resource 物件
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 新增後置處理器,如果有 bean 實現了 ApplicationContextAware,BeanFactory 使用 ApplicationContextAwareProcessor 去處理
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);
beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);
// 這些註冊為 bean,比如可以直接 @Autorired BeanFactory beanFactory 來注入 BeanFactory
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 新增後置處理器,讓 BeanFactory 可以處理時間釋出與監聽
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// GraalVM 支援,java 虛擬機器一般都是 hotspot VM
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 再實現註冊一些預設的 bean
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());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
步驟4:擴充套件 BeanFactory
上一步已經賦能了,這裡再次賦能,這是一個鉤子方法,沒有實現,所以專門提供給子類的
比如 SpringMVC 擴充套件後我們標註 @Controller 就會把這個 bean 注入到容器中
步驟5:執行 BeanFactoryPostProcesser
步驟 3 給 BeanFactory 放入了一批後置處理器,這一步就是要執行他們
// org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// this.getBeanFactoryPostProcessors() 就是獲取所有 bean 工廠後置處理器,此時是空的 invokeBeanFactoryPostProcessors 會去找
// invokeBeanFactoryPostProcessors 首先找到所有實現了 BeanFactoryPostProcessor 介面的 bean,然後挨個呼叫其 postProcessBeanFactory 方法
// BeanFactoryPostProcessor 幹嘛的?修改 bean 定義的,在建立前對 bean 定義做一些修改,後續根據修改後的定義來建立 bean
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
// GraalVM 支援
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
// org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
...
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> 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)) {
// 找到所有實現了 BeanFactoryPostProcessor 的類
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
...
}