spring擴展啓動流程-refresh
在spring-webmvc啓動流程中,咱們在對wac的刷新過程並無詳細的解釋,只是一筆帶過。java
無論是從ContextLoaderListener進入的,仍是Servlet的init方法進入的,都離不開spring總體的初始化。僅僅有bean的讀取,加載的spring是不完整的,spring還須要這些擴展的部分,讓spring更完善,先來看看入口吧。web
// ContextLoader.java protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) { //... wac.refresh(); }
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) { //... wac.refresh(); }
refresh函數中幾乎包含了ApplicationContext提供的全部功能,並且此函數中的邏輯很清楚,瞅一下吧。spring
調試能夠直接從ClassPathXmlApplicationContext這個類駛入,構造方法直接就能駛入這個方法,並初始化完成整個環境。緩存
// AbstractApplicationContext.java public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. // 準備刷新的上下文環境 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. // 初始化BeanFactory,並進行xml文件讀取 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. // 對BeanFactory進行各類功能填充 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. // 註冊攔截Bean建立的Bean處理器,這裏只是註冊,調用是在getBean的時候 registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // 爲上下文初始化Message源,即不一樣語言的消息體,國際化處理 initMessageSource(); // Initialize event multicaster for this context. // 初始化應用消息廣播器,並放入"ApplicationEventMulticaster" Bean中 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // 留給子類來初始化其餘的Bean onRefresh(); // Check for listener beans and register them. // 在全部註冊的Bean中查找Listenter bean,註冊到消息廣播器中 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. //初始化剩下的單例(非惰性) finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // 完成刷新過程,通知生命週期處理器lifecycleProcessor完成刷新過程,同時發出ContextRefreshEvent通知別人 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(); //屬性文件驗證,確保須要的文件都已經放入環境中 getEnvironment().validateRequiredProperties(); //... }
初始化BeanFactory,對xml文件的讀取,就是從這個地方開始的,使用的是默認的DefaultListableBeanFactory。mvc
//AbstractApplicationContext.java protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { //初始化BeanFactory refreshBeanFactory(); //返回初始化以後的BeanFactory return getBeanFactory(); }
//AbstractRefreshableApplicationContext.java protected final void refreshBeanFactory() throws BeansException { //檢查是否已經有了初始化的BeanFactory if (hasBeanFactory()) { //銷燬全部的bean destroyBeans(); //關閉並銷燬BeanFactory closeBeanFactory(); } try { //建立默認的DefaultListableBeanFactory,子類能夠覆蓋該方法 DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); //定製BeanFactory,包括是否容許覆蓋同名稱的不一樣定義的對象以及循環依賴 customizeBeanFactory(beanFactory); //初始化XmlBeanDefinitionReader,並進行xml文件的解析。 loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) {...} } protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { //設置是否容許同名不一樣定義的bean覆蓋 if (this.allowBeanDefinitionOverriding != null) { beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } //設置是否容許循環依賴 if (this.allowCircularReferences != null) { beanFactory.setAllowCircularReferences(this.allowCircularReferences); } }
至此,spring已經完成了對配置的解析,ApplicationContext在功能上的擴展也由此開始。app
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { beanFactory.setBeanClassLoader(getClassLoader()); //設置表達式語言處理器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); //設置一個默認的屬性解析器PropertyEditor beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); //添加BeanPostProcessor 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); //註冊依賴解析,也是spring的bean,可是會特殊一些,下邊會有解釋 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)); //增長對AspectJ的支持 if (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()); } }
主要擴展: 1. 增長對SPEL語言的支持; 2. 增長對屬性編輯器的支持,這些PropertyEditors在這裏只是註冊,使用的時候是將bean包裝成BeanWrapper,包裝後的BeanWrapper的就包含了全部的這些PropertyEditors,以便後期給bean設置屬性的時候使用; 3. 增長對一些內置類(實際上就是前置處理器),好比Aware接口的信息注入; 4. 設置依賴功能可忽略的接口; 5. 註冊一些固定的bean,這些都是特殊的依賴解析,好比當註冊了BeanFactory.class的依賴解析以後,當bean的屬性注入的時候,一旦檢測到屬性爲BeanFactory類型便會將beanFactory的實例注入進去; 6. 增長對AspectJ的支持; 7. 將相關環境變量及屬性以單例模式註冊。
激活註冊的BeanFactoryPostProcessor。這個接口跟BeanPostProcessor相似,能夠對bean的定義(配置元數據)進行處理,做用範圍是容器級的,只對本身的容器的bean進行處理。典型應用PropertyPlaceholderConfigurer。編輯器
這部分代碼有點長,不貼了,本身去看吧。函數
註冊全部的bean先後置處理器BeanPostProcessor,這裏只是註冊,調用是在bean建立的時候。post
代碼也有點長,不貼了,本身去看吧~~ui
國際化處理,若是想使用自定義的,bean name是指定了的MESSAGE_SOURCE_BEAN_NAME = "messageSource"。
protected void initMessageSource() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); //根據指定的名稱查找messageSource,若是容器中註冊了指定名稱的messageSource,就使用註冊的 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 { //容器中沒有註冊指定名稱的messageSource,使用默認的DelegatingMessageSource DelegatingMessageSource dms = new DelegatingMessageSource(); dms.setParentMessageSource(getInternalParentMessageSource()); this.messageSource = dms; beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); //...日誌 } }
初始化應用的事件廣播器,用於事件監聽,邏輯跟初始化國際化MessageSource是同樣的,也是有一個特定的名稱。若是beanFactory有就是用註冊的,若是沒有就是用默認的SimpleApplicationEventMulticaster。
應用中的listener都是註冊到這個廣播器,由廣播器統一廣播的。
在全部註冊的Bean中查找Listenter bean,註冊到消息廣播器中。
protected void registerListeners() { // 首先註冊靜態註冊的監聽器(代碼註冊的) for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // 獲取容器中全部配置的listener並註冊 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // 對earlyApplicationEvents這些事件進行廣播,實際上就是遍歷全部的listener,找到能夠處理event的listener處理 Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
初始化剩下的非惰性單例,若是某個單例依賴了惰性的單例,那麼這個惰性的單例也會被初始化,這個很好理解吧。
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)); } //則註冊默認的嵌入值解析器 //例如PropertyPlaceholderConfigurer bean)以前註冊過: //主要用於註解屬性值的解析。 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); //凍結bean定義(BeanDefinition),表示全部的bean定義進不被修改或進行進一步處理 beanFactory.freezeConfiguration(); //初始化非惰性單例,實際上就是遍歷全部的beanName,而後一一調用getBean() beanFactory.preInstantiateSingletons(); }
protected void finishRefresh() { //清除上下文級別(context-level)的資源緩存,好比由scanning產生的ASM元數據 clearResourceCaches(); //初始化LifecycleProcessor initLifecycleProcessor(); //使用LifecycleProcessor來啓動Lifecycle子類 getLifecycleProcessor().onRefresh(); //上下文刷新完成,發佈事件 publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); }
初始化LifecycleProcessor的時候,跟初始化MessageResource同樣,沒有自定義的就是用默認的DefaultLifecycleProcessor。
getLifecycleProcessor().onRefresh()會使用咱們註冊的LyfecycleProcessor來啓動咱們註冊的SmartLifeCycle的子類。看一下代碼吧。
//默認的DefaultLifecycleProcessor.java public void onRefresh() { startBeans(true); this.running = true; } private void startBeans(boolean autoStartupOnly) { //獲取全部的LifeCycle類型的bean Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans(); Map<Integer, LifecycleGroup> phases = new HashMap<>(); lifecycleBeans.forEach((beanName, bean) -> { //默認的DefaultLifecycleProcessor只會啓動SmartLifecycle的,或者非自動啓動的類型 //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); //添加到須要啓動的集合中 phases.put(phase, group); } group.add(beanName, bean); } }); //啓動須要啓動的這些LifeCycle if (!phases.isEmpty()) { List<Integer> keys = new ArrayList<>(phases.keySet()); Collections.sort(keys); for (Integer key : keys) { phases.get(key).start(); } } }
over ...