本篇內(nèi)容介紹了“spring擴(kuò)展啟動(dòng)流程refresh詳解”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),綏寧企業(yè)網(wǎng)站建設(shè),綏寧品牌網(wǎng)站建設(shè),網(wǎng)站定制,綏寧網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,綏寧網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
spring擴(kuò)展啟動(dòng)流程-refresh
在spring-webmvc啟動(dòng)流程中,我們?cè)趯?duì)wac的刷新過(guò)程并沒有詳細(xì)的解釋,只是一筆帶過(guò)。
不管是從ContextLoaderListener進(jìn)入的,還是Servlet的init方法進(jìn)入的,都離不開spring整體的初始化。僅僅有bean的讀取,加載的spring是不完整的,spring還需要這些擴(kuò)展的部分,讓spring更完善,先來(lái)看看入口吧。
// ContextLoader.java protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) { //... wac.refresh(); }
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) { //... wac.refresh(); }
refresh函數(shù)中幾乎包含了ApplicationContext提供的所有功能,而且此函數(shù)中的邏輯很清楚,瞅一下吧。
調(diào)試可以直接從ClassPathXmlApplicationContext這個(gè)類駛?cè)耄瑯?gòu)造方法直接就能駛?cè)脒@個(gè)方法,并初始化完成整個(gè)環(huán)境。
// AbstractApplicationContext.java public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. // 準(zhǔn)備刷新的上下文環(huán)境 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. // 初始化BeanFactory,并進(jìn)行xml文件讀取 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. // 對(duì)BeanFactory進(jìn)行各種功能填充 prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // 子類覆蓋做額外的處理 postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. // 激活各種BeanFactory處理器 invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // 注冊(cè)攔截Bean創(chuàng)建的Bean處理器,這里只是注冊(cè),調(diào)用是在getBean的時(shí)候 registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // 為上下文初始化Message源,即不同語(yǔ)言的消息體,國(guó)際化處理 initMessageSource(); // Initialize event multicaster for this context. // 初始化應(yīng)用消息廣播器,并放入"ApplicationEventMulticaster" Bean中 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // 留給子類來(lái)初始化其他的Bean onRefresh(); // Check for listener beans and register them. // 在所有注冊(cè)的Bean中查找Listenter bean,注冊(cè)到消息廣播器中 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. //初始化剩下的單例(非惰性) finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // 完成刷新過(guò)程,通知生命周期處理器lifecycleProcessor完成刷新過(guò)程,同時(shí)發(fā)出ContextRefreshEvent通知?jiǎng)e人 finishRefresh(); } catch (BeansException ex) { // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } } }
//AbstractApplicationContext.java protected void prepareRefresh() { //... //留給子類覆蓋 initPropertySources(); //屬性文件驗(yàn)證,確保需要的文件都已經(jīng)放入環(huán)境中 getEnvironment().validateRequiredProperties(); //... }
初始化BeanFactory,對(duì)xml文件的讀取,就是從這個(gè)地方開始的,使用的是默認(rèn)的DefaultListableBeanFactory。
//AbstractApplicationContext.java protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { //初始化BeanFactory refreshBeanFactory(); //返回初始化之后的BeanFactory return getBeanFactory(); }
//AbstractRefreshableApplicationContext.java protected final void refreshBeanFactory() throws BeansException { //檢查是否已經(jīng)有了初始化的BeanFactory if (hasBeanFactory()) { //銷毀所有的bean destroyBeans(); //關(guān)閉并銷毀BeanFactory closeBeanFactory(); } try { //創(chuàng)建默認(rèn)的DefaultListableBeanFactory,子類可以覆蓋該方法 DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); //定制BeanFactory,包括是否允許覆蓋同名稱的不同定義的對(duì)象以及循環(huán)依賴 customizeBeanFactory(beanFactory); //初始化XmlBeanDefinitionReader,并進(jìn)行xml文件的解析。 loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) {...} } protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { //設(shè)置是否允許同名不同定義的bean覆蓋 if (this.allowBeanDefinitionOverriding != null) { beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } //設(shè)置是否允許循環(huán)依賴 if (this.allowCircularReferences != null) { beanFactory.setAllowCircularReferences(this.allowCircularReferences); } }
至此,spring已經(jīng)完成了對(duì)配置的解析,ApplicationContext在功能上的擴(kuò)展也由此開始。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { beanFactory.setBeanClassLoader(getClassLoader()); //設(shè)置表達(dá)式語(yǔ)言處理器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); //設(shè)置一個(gè)默認(rèn)的屬性解析器PropertyEditor beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); //添加BeanPostProcessor beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); //設(shè)置幾個(gè)忽略自動(dòng)裝配的接口 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); //注冊(cè)依賴解析,也是spring的bean,但是會(huì)特殊一些,下邊會(huì)有解釋 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); //添加BeanPostProcessor beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); //增加對(duì)AspectJ的支持 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } //添加默認(rèn)的系統(tǒng)環(huán)境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()); } }
主要擴(kuò)展: 1. 增加對(duì)SPEL語(yǔ)言的支持; 2. 增加對(duì)屬性編輯器的支持,這些PropertyEditors在這里只是注冊(cè),使用的時(shí)候是將bean包裝成BeanWrapper,包裝后的BeanWrapper的就包含了所有的這些PropertyEditors,以便后期給bean設(shè)置屬性的時(shí)候使用; 3. 增加對(duì)一些內(nèi)置類(實(shí)際上就是前置處理器),比如Aware接口的信息注入; 4. 設(shè)置依賴功能可忽略的接口; 5. 注冊(cè)一些固定的bean,這些都是特殊的依賴解析,比如當(dāng)注冊(cè)了BeanFactory.class的依賴解析之后,當(dāng)bean的屬性注入的時(shí)候,一旦檢測(cè)到屬性為BeanFactory類型便會(huì)將beanFactory的實(shí)例注入進(jìn)去; 6. 增加對(duì)AspectJ的支持; 7. 將相關(guān)環(huán)境變量及屬性以單例模式注冊(cè)。
激活注冊(cè)的BeanFactoryPostProcessor。這個(gè)接口跟BeanPostProcessor類似,可以對(duì)bean的定義(配置元數(shù)據(jù))進(jìn)行處理,作用范圍是容器級(jí)的,只對(duì)自己的容器的bean進(jìn)行處理。典型應(yīng)用PropertyPlaceholderConfigurer。
這部分代碼有點(diǎn)長(zhǎng),不貼了,自己去看吧。
注冊(cè)所有的bean前后置處理器BeanPostProcessor,這里只是注冊(cè),調(diào)用是在bean創(chuàng)建的時(shí)候。
代碼也有點(diǎn)長(zhǎng),不貼了,自己去看吧~~
國(guó)際化處理,如果想使用自定義的,bean name是指定了的MESSAGE_SOURCE_BEAN_NAME = "messageSource"。
protected void initMessageSource() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); //根據(jù)指定的名稱查找messageSource,如果容器中注冊(cè)了指定名稱的messageSource,就使用注冊(cè)的 if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) { HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource; if (hms.getParentMessageSource() == null) { hms.setParentMessageSource(getInternalParentMessageSource()); } } //...日志 } else { //容器中沒有注冊(cè)指定名稱的messageSource,使用默認(rèn)的DelegatingMessageSource DelegatingMessageSource dms = new DelegatingMessageSource(); dms.setParentMessageSource(getInternalParentMessageSource()); this.messageSource = dms; beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); //...日志 } }
初始化應(yīng)用的事件廣播器,用于事件監(jiān)聽,邏輯跟初始化國(guó)際化MessageSource是一樣的,也是有一個(gè)特定的名稱。如果beanFactory有就是用注冊(cè)的,如果沒有就是用默認(rèn)的SimpleApplicationEventMulticaster。
應(yīng)用中的listener都是注冊(cè)到這個(gè)廣播器,由廣播器統(tǒng)一廣播的。
在所有注冊(cè)的Bean中查找Listenter bean,注冊(cè)到消息廣播器中。
protected void registerListeners() { // 首先注冊(cè)靜態(tài)注冊(cè)的監(jiān)聽器(代碼注冊(cè)的) for (ApplicationListener> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // 獲取容器中所有配置的listener并注冊(cè) String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // 對(duì)earlyApplicationEvents這些事件進(jìn)行廣播,實(shí)際上就是遍歷所有的listener,找到可以處理event的listener處理 SetearlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
初始化剩下的非惰性單例,如果某個(gè)單例依賴了惰性的單例,那么這個(gè)惰性的單例也會(huì)被初始化,這個(gè)很好理解吧。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // 初始化ConversionService,跟PropertyEditor類似 if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } //則注冊(cè)默認(rèn)的嵌入值解析器 //例如PropertyPlaceholderConfigurer bean)之前注冊(cè)過(guò): //主要用于注解屬性值的解析。 if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } //單例bean初始化之前首先初始化LoadTimeWeaverAware,以支持aop,AspectJ String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } beanFactory.setTempClassLoader(null); //凍結(jié)bean定義(BeanDefinition),表示所有的bean定義進(jìn)不被修改或進(jìn)行進(jìn)一步處理 beanFactory.freezeConfiguration(); //初始化非惰性單例,實(shí)際上就是遍歷所有的beanName,然后一一調(diào)用getBean() beanFactory.preInstantiateSingletons(); }
protected void finishRefresh() { //清除上下文級(jí)別(context-level)的資源緩存,比如由scanning產(chǎn)生的ASM元數(shù)據(jù) clearResourceCaches(); //初始化LifecycleProcessor initLifecycleProcessor(); //使用LifecycleProcessor來(lái)啟動(dòng)Lifecycle子類 getLifecycleProcessor().onRefresh(); //上下文刷新完成,發(fā)布事件 publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); }
初始化LifecycleProcessor的時(shí)候,跟初始化MessageResource一樣,沒有自定義的就是用默認(rèn)的DefaultLifecycleProcessor。
getLifecycleProcessor().onRefresh()會(huì)使用我們注冊(cè)的LyfecycleProcessor來(lái)啟動(dòng)我們注冊(cè)的SmartLifeCycle的子類。看一下代碼吧。
//默認(rèn)的DefaultLifecycleProcessor.java public void onRefresh() { startBeans(true); this.running = true; } private void startBeans(boolean autoStartupOnly) { //獲取所有的LifeCycle類型的bean MaplifecycleBeans = getLifecycleBeans(); Map phases = new HashMap<>(); lifecycleBeans.forEach((beanName, bean) -> { //默認(rèn)的DefaultLifecycleProcessor只會(huì)啟動(dòng)SmartLifecycle的,或者非自動(dòng)啟動(dòng)的類型 //SmartLifecycle繼承了Phases接口 if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) { int phase = getPhase(bean); LifecycleGroup group = phases.get(phase); if (group == null) { group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly); //添加到需要啟動(dòng)的集合中 phases.put(phase, group); } group.add(beanName, bean); } }); //啟動(dòng)需要啟動(dòng)的這些LifeCycle if (!phases.isEmpty()) { List keys = new ArrayList<>(phases.keySet()); Collections.sort(keys); for (Integer key : keys) { phases.get(key).start(); } } }
“spring擴(kuò)展啟動(dòng)流程refresh詳解”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!