Spring IOC源碼:簡單易懂的Spring IOC 思路介紹
Spring IOC源碼:核心流程介紹
Spring IOC源碼:ApplicationContext刷新前準備工作
Spring IOC源碼:obtainFreshBeanFactory 詳解(上)
Spring IOC源碼:obtainFreshBeanFactory 詳解(中)
Spring IOC源碼:obtainFreshBeanFactory 詳解(下)
Spring IOC源碼:<context:component-scan>源碼詳解
Spring IOC源碼:invokeBeanFactoryPostProcessors 后置處理器詳解
Spring IOC源碼:registerBeanPostProcessors 詳解
Spring IOC源碼:實例化前的準備工作
Spring IOC源碼:finishBeanFactoryInitialization詳解
Spring IoC源碼:getBean 詳解
Spring IoC源碼:createBean( 上)
Spring IoC源碼:createBean( 中)
Spring IoC源碼:createBean( 下)
Spring IoC源碼:finishRefresh 完成刷新詳解
當完成Bean定義信息解析、Bean的創(chuàng)建、初始化流程之后,到最后一個方法finishRefresh完成上下文刷新。
正文來到refresh()方法中的最后一個方法finishRefresh();
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) { // 容器刷新前準備工作
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//創(chuàng)建Bean工廠,解析配置
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// bean工廠準備工作
prepareBeanFactory(beanFactory);
try { //拓展接口,留給子類進行實現(xiàn)拓展
postProcessBeanFactory(beanFactory);
// 注冊執(zhí)行,BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 注冊創(chuàng)建BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// 這個方法主要作用就是使用國際化,定制不同的消息文本,比如定義了一個Person的Bean,它有name屬性,我們需要在不同的國家展示對應國家所在語言名稱,這時候就可以使用國際化了。
initMessageSource();
// Initialize event multicaster for this context.
//初始化應用事件廣播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//拓展接口,留給子類進行實現(xiàn)拓展,springboot就對該方法進行了處理
onRefresh();
// Check for listener beans and register them.
//將內部的、以及我們自定義的監(jiān)聽器添加到緩存中,為后續(xù)邏輯處理做準備。還有添加事件源到緩存中。
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//實例化剩下非懶加載的Bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
//使用應用事件廣播器推送上下文刷新完畢事件(ContextRefreshedEvent )到相應的監(jiān)聽器。
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.
//執(zhí)行相關銷毀方法
destroyBeans();
// Reset 'active' flag.
//重置上下文刷新狀態(tài)
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();
}
}
}
finishRefresh(),見方法1詳解
方法1:finishRefreshprotected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).
//清除該資源加載器中的所有資源緩存
clearResourceCaches();
// Initialize lifecycle processor for this context.
//初始化LifecycleProcessor。
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
//調用LifecycleProcessor的onRefresh方法進行刷新
getLifecycleProcessor().onRefresh();
// 發(fā)布事件
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
initLifecycleProcessor(),見方法2詳解
getLifecycleProcessor().onRefresh(),見方法3詳解
publishEvent(new ContextRefreshedEvent(this)),見方法4詳解
方法2:initLifecycleProcessorprotected void initLifecycleProcessor() {//獲取BeanFactory工廠
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//判斷是否存在名稱為lifecycleProcessor的Bean或定義信息
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) { //獲取或創(chuàng)建LifecycleProcessor
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
if (logger.isTraceEnabled()) { logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
}
else { //bean工廠中不存在該bean的信息,則創(chuàng)建一個默認的
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
//注冊添加到一級緩存中
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isTraceEnabled()) { logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
}
}
}
方法3:onRefreshpublic void onRefresh() {startBeans(true);
this.running = true;
}
private void startBeans(boolean autoStartupOnly) {//獲取Lifecycle類型的bean集合
MaplifecycleBeans = getLifecycleBeans();
Mapphases = new HashMap<>();
lifecycleBeans.forEach((beanName, bean) ->{ //autoStartupOnly 為true時,代表是容器自動啟動調用,這時只有SmartLifecycle 類型且isAutoStartup為TRUE才會調用
//如果autoStartupOnly 為false,代表是手動調用,會調用所有的Lifecycle
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) { //獲取階段值,即優(yōu)先級值。如果有實現(xiàn)Phased接口,則通過getPhase方法返回數(shù)值,值越小則排序越前
int phase = getPhase(bean);
//判斷容器中是否已存在,不存在則創(chuàng)建LifecycleGroup 類型對象
LifecycleGroup group = phases.get(phase);
if (group == null) {group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
phases.put(phase, group);
}
group.add(beanName, bean);
}
});
if (!phases.isEmpty()) { Listkeys = new ArrayList<>(phases.keySet());
//排序
Collections.sort(keys);
//遍歷調用
for (Integer key : keys) { phases.get(key).start();
}
}
}
方法4:publishEventprotected void publishEvent(Object event, @Nullable ResolvableType eventType) {Assert.notNull(event, "Event must not be null");
// Decorate event as an ApplicationEvent if necessary
//判斷事件是否繼承了ApplicationEvent接口
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) { applicationEvent = (ApplicationEvent) event;
}
else { //將事件封裝成PayloadApplicationEvent類型的事件
applicationEvent = new PayloadApplicationEvent<>(this, event);
//設置事件類型
if (eventType == null) { eventType = ((PayloadApplicationEvent>) applicationEvent).getResolvableType();
}
}
// Multicast right now if possible - or lazily once the multicaster is initialized
if (this.earlyApplicationEvents != null) { this.earlyApplicationEvents.add(applicationEvent);
}
else { //使用多播器發(fā)布事件
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// Publish event via parent context as well...
//使用父上下文進行發(fā)布事件
if (this.parent != null) { if (this.parent instanceof AbstractApplicationContext) { ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else { this.parent.publishEvent(event);
}
}
}
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType),見方法5詳解
方法5:multicastEventpublic void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {//獲取事件源類型
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
//根據(jù)事件類型獲取對應類型的監(jiān)聽器
for (ApplicationListener>listener : getApplicationListeners(event, type)) { //調用監(jiān)聽器的onApplicationEvent方法
if (executor != null) { executor.execute(() ->invokeListener(listener, event));
}
else { invokeListener(listener, event);
}
}
}
invokeListener(listener, event)),見方法6詳解
方法6:invokeListenerprotected void invokeListener(ApplicationListener>listener, ApplicationEvent event) {//獲取錯誤處理器
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) { try { //調用監(jiān)聽器處理方法
doInvokeListener(listener, event);
}
catch (Throwable err) { errorHandler.handleError(err);
}
}
else { doInvokeListener(listener, event);
}
}
doInvokeListener(listener, event),見方法7詳解
方法7:doInvokeListenerprivate void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {try { //調用監(jiān)聽器的onApplicationEvent方法,并傳入事件
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) { String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass())) { // Possibly a lambda-defined listener which we could not resolve the generic event type for
// ->let's suppress the exception and just log a debug message.
Log logger = LogFactory.getLog(getClass());
if (logger.isTraceEnabled()) {logger.trace("Non-matching event type for listener: " + listener, ex);
}
}
else { throw ex;
}
}
}
總結Spring IOC中refresh()所有方法都講解完了,這里面的內容非車多,花了不少時間在看,但是感覺還是比較粗糙,文章中有很多點理解得不是很到位,如果大家有更好的見解,歡迎指點評論。學習IOC過程是非常枯燥的,但是耐心去看真的能發(fā)現(xiàn)這個框架設計真的很厲害,拓展性做得很好,有很多地方值得我們在工作中進行參考開發(fā)。后續(xù)會發(fā)布Spring 系列的其它文章,如AOP,只有不斷的學習,才能加深對Spring框架的理解。
你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧
當前標題:SpringIoC源碼:finishRefresh完成刷新詳解-創(chuàng)新互聯(lián)
URL分享:http://aaarwkj.com/article34/csoise.html
成都網站建設公司_創(chuàng)新互聯(lián),為您提供網站內鏈、動態(tài)網站、網站改版、ChatGPT、小程序開發(fā)、做網站
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內容