refresh方法介紹
bean配置讀取和加載入口
在這個方法內完成sping框架啟動流程
首先從SpringBoot的啟動run方法,進入到AbstractApplicationContext類refresh方式涉及到下面多個子方法的調用
@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. 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); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // 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) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + 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(); } } }
1、prepareRefresh();
容器狀態設置
初始化屬性設置
檢查必備屬性是否存在
2、obtainFreshBeanFactory
設置beanFactory序列化id
獲取beanFactory
3、prepareBeanFactory(beanFactory);
設置beanFactory一些屬性
添加后置處理器
設置忽略的自動裝配接口
注冊一些主件
4、postProcessBeanFactory(beanFactory);
子類重寫以在BeanFactory完成創建后做進一步設置
5、invokeBeanFactoryPostProcessors(beanFactory);
調用BeanDefinitionRegistryPostProcessor實現向容器內添加bean的定義 (使用參考: 實現BeanDefinitionRegistryPostProcessor)
調用BeanFactoryPostProcessor實現向容器內添加bean的定義添加屬性
BeanFactoryPostProcessor的使用
1)創建Teacher類
@Component public class Teacher { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
2)創建類MyBeanFactoryPostProcessor ,實現BeanFactoryPostProcessor接口。並且給teacher增加name屬性值為Nick
@Component public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { BeanDefinition teacher = configurableListableBeanFactory.getBeanDefinition("teacher"); MutablePropertyValues propertyValues = teacher.getPropertyValues(); propertyValues.addPropertyValue("name","Nick"); } }
3)運行測試方法testTeacher
結果為
6、registerBeanPostProcessors(beanFactory);
找到BeanPostPocessor的實現
排序后注冊進容器內
7、initMessageSource();
初始化國際化相關屬性
8、 initApplicationEventMulticaster();
初始化事件廣播器。注冊到容器當中
9、onRefresh();
創建web容器。如果是web環境當中,會進入如下圖的方法,構建一個web容器,如tomcat,jetty等。
10、registerListeners();
添加容器內事件監聽器至事件廣播器中
派發早期事件
11、finishBeanFactoryInitialization(beanFactory);
初始化剩下的單實例Bean
12、finishRefresh();
初始化生命周期處理器
調用生命周期處理器的onRefresh方法
發布ContextRefreshedEvent 事件
JMX相關處理
13、 resetCommonCaches();
清除緩存