摘要:重要的會在后面拎出來多帶帶詳解加鎖,防止在過程中,重啟或銷毀造成不必要的問題準備此上下文以進行刷新,設置其啟動日期和,活動標志以及執行屬性源的任何初始化,校驗配置文件。以后所有的相關的操作其實是委托給這個實例來處理的。
1、先上測試代碼
public static void main(String[] args){ //配置文件來啟動一個 ApplicationContext ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml"); System.out.println("context 啟動成功"); //從context 中取出我們的 Bean,而不是用 new HelloServiceImpl() 這種方式 HelloService helloService = context.getBean(HelloService.class); // 這句將輸出: ok System.out.println(helloService.get(); } public interface HelloService { String get(); } public class HelloServiceImpl implements HelloService{ @Override public String get() { return "ok"; } }
在resource目錄下創建application.xml
2、我看一下new ClassPathXmlApplicationContext("classpath:application.xml")干了些什么
跟蹤可以發現ClassPathXmlApplicationContext繼承ApplicationContext
下面沿著代碼一步步看都干了些什么:
public ClassPathXmlApplicationContext(String configLocation) throws BeansException { this(new String[] {configLocation}, true, null); } public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { //獲取資源管理器 super(parent); //設置配置文件路徑,即classpath:application.xml,當然結果是個數組 setConfigLocations(configLocations); //這里是我們的重點,重新創建一個AbstractApplicationContext if (refresh) { refresh(); } } //AbstractApplicationContext中實現了super(parent) public AbstractApplicationContext() { this.resourcePatternResolver = getResourcePatternResolver(); }3、看一下refresh方法的執行過程
一些不重要的就不把代碼貼出來了,只寫方法注釋。重要的會在后面拎出來多帶帶詳解
public void refresh() throws BeansException, IllegalStateException { //加鎖,防止在refresh過程中,重啟或銷毀造成不必要的問題 synchronized (this.startupShutdownMonitor) { // 準備此上下文以進行刷新,設置其啟動日期和,活動標志以及執行屬性源的任何初始化,校驗 xml 配置文件。 prepareRefresh(); // 創建beanFactory,解析配置文件為一個個beanDefinition(類似map,key是beanname,value是bean屬性(總有的有,beanname,是否懶加載,作用范圍,依賴等等)),然后放到beanFactory中,詳細看步驟4 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 設置 BeanFactory 的類加載器,添加幾個 BeanPostProcessor,手動注冊幾個特殊的 bean,詳情看步驟5 prepareBeanFactory(beanFactory); try { //允許上下文子類在初始化的時候對beanFactory進行修改 postProcessBeanFactory(beanFactory); //調用所有beanFactoryPostProcessor對beanDefinite信息進行修改,詳情見步驟6 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(); } } }4、ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()執行過程
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { //關閉舊的 BeanFactory (如果有),創建新的 BeanFactory,加載 Bean 定義、注冊 Bean 等 refreshBeanFactory(); //返回剛剛創建的beanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; } protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) {//是否已經存在beanFactory destroyBeans();//銷毀所有bean closeBeanFactory();//關閉beanFactory } try { //創建DefaultListableBeanFactory,為什么用這個,可以參考beanFactory繼承結構 //ApplicationContext 繼承自 BeanFactory,但是它不應該被理解為 BeanFactory 的實現類,而是說其內部持有一個實例化的 BeanFactory(DefaultListableBeanFactory)。以后所有的 BeanFactory 相關的操作其實是委托給這個實例來處理的。 DefaultListableBeanFactory beanFactory = createBeanFactory(); //序列化id beanFactory.setSerializationId(getId()); //設置 BeanFactory 的兩個配置屬性:是否允許 Bean 覆蓋、是否允許循環引用 customizeBeanFactory(beanFactory); //解析配置文件的封裝成beandefinite,加載到beanFactory(解析過程就不多少了,想了解的同學可以看看) loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } } protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { if (this.allowBeanDefinitionOverriding != null) { //設置是否允許bean被覆蓋 beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } if (this.allowCircularReferences != null) { //設置是否可以循環引用 beanFactory.setAllowCircularReferences(this.allowCircularReferences); } }
了解完后,我們回到步驟3繼續跟代碼
5、prepareBeanFactory(beanFactory)詳情protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 設置類加載器 // return (this.classLoader != null ? this.classLoader : ClassUtils.getDefaultClassLoader()) //這里是當前ApplicationContext類的類加載器 beanFactory.setBeanClassLoader(getClassLoader()); //設置bean的表達式解析器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); //添加注冊編輯屬性 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // 添加一個beanPostProcessor,這個挺重要 //它會檢測該對象是否實現了xxxAware接口,并將相關的xxxAware實例注入給bean,如BeanNameAware等 //關于xxxAware的作用可以參考這個http://www.what21.com/article/view/b_java_1484728658282.html beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 下面幾行的意思就是,如果某個 bean 依賴于以下幾個接口的實現類,在自動裝配的時候忽略它們, // Spring 會通過其他方式來處理這些依賴。 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // 下面是處理幾個特殊的bean注入相應的值 // beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // 添加一個beanPostProcessor,在bean被實例化后,如果是ApplicationListener的子類,則加到listeners中 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // 如果bean是LoadTimeWeaver,則織入(在運行時織入,是和AOP相似,只是時機不一樣) 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()); } } 我們回到步驟3繼續6、invokeBeanFactoryPostProcessors(beanFactory)
//實例化并調用所有已注冊的BeanFactoryPostProcessor bean protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { //getBeanFactoryPostProcessors():獲取所有的beanFactoryPostProcessor PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, ListbeanFactoryPostProcessors) { // 記錄已經遍歷的beanFactoryPostProcessor Set processedBeans = new HashSet (); if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List regularPostProcessors = new LinkedList (); List registryPostProcessors = new LinkedList (); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { //BeanDefinitionRegistryPostProcessor的子類放入registryPostProcessors中,其他放在regularPostProcessors中 if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryPostProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryPostProcessor.postProcessBeanDefinitionRegistry(registry); registryPostProcessors.add(registryPostProcessor); } else { regularPostProcessors.add(postProcessor); } } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // Separate between BeanDefinitionRegistryPostProcessors that implement // PriorityOrdered, Ordered, and the rest. //獲取beanFactory中所有BeanDefinitionRegistryPostProcessor String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); // 調用實現PriorityOrdered的BeanDefinitionRegistryPostProcessors List priorityOrderedPostProcessors = new ArrayList (); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(beanFactory, priorityOrderedPostProcessors); registryPostProcessors.addAll(priorityOrderedPostProcessors); invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry); // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); List orderedPostProcessors = new ArrayList (); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(beanFactory, orderedPostProcessors); registryPostProcessors.addAll(orderedPostProcessors); invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry); // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class); registryPostProcessors.add(pp); processedBeans.add(ppName); pp.postProcessBeanDefinitionRegistry(registry); reiterate = true; } } } // Now, invoke the postProcessBeanFactory callback of all processors handled so far. invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List priorityOrderedPostProcessors = new ArrayList (); List orderedPostProcessorNames = new ArrayList (); List 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)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(beanFactory, priorityOrderedPostProcessors); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // Next, invoke the BeanFactoryPostProcessors that implement Ordered. List orderedPostProcessors = new ArrayList (); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(beanFactory, orderedPostProcessors); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // Finally, invoke all other BeanFactoryPostProcessors. List nonOrderedPostProcessors = new ArrayList (); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // Clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values... beanFactory.clearMetadataCache(); }
未完繼續
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/75964.html
摘要:本篇文章是源碼解析上的續集,上一篇文章介紹了使用的方式啟動,然后追蹤了容器的創建配置文件的解析的注冊等。前方超長篇幅預警。。。記錄依賴關系通過類型裝配。這也是作者第一次閱讀開源框架的源碼,如文章有錯誤之處還請您費心指出。 注意,看完這篇文章需要很長很長很長時間。。。 本篇文章是SpringIOC源碼解析(上)的續集,上一篇文章介紹了使用XML的方式啟動Spring,然后追蹤了BeanF...
摘要:不同與其它中間件框架,中有大量的業務代碼,它向我們展示了大神是如何寫業務代碼的依賴的層次結構,如何進行基礎包配置,以及工具類編寫,可以稱之為之最佳實踐。代碼參考視圖解析器,這里的配置指的是不檢查頭,而且默認請求為格式。 不同與其它中間件框架,Apollo中有大量的業務代碼,它向我們展示了大神是如何寫業務代碼的:maven依賴的層次結構,如何進行基礎包配置,以及工具類編寫,可以稱之為sp...
摘要:對于開發者來說,無疑是最常用也是最基礎的框架之一。概念上的東西還是要提一嘴的用容器來管理。和是容器的兩種表現形式。定義了簡單容器的基本功能。抽象出一個資源類來表示資源調用了忽略指定接口的自動裝配功能委托解析資源。 對于Java開發者來說,Spring無疑是最常用也是最基礎的框架之一。(此處省略1w字吹Spring)。相信很多同行跟我一樣,只是停留在會用的階段,比如用@Component...
摘要:即,的后置處理器,它的作用就是在的初始化方法前跟后進行攔截處理。如何注冊后置處理器我們暫不作分析,著重說一下,后置處理器是如何工作的。 BeanPostProcessor即,Bean的后置處理器,它的作用就是在Bean的初始化方法前跟后進行攔截處理。我們都知道,要想在Bean的初始化方法前后進行工作,那必須在Bean實例創建完成之后,init方法執行之前,后置處理器就已經在容器中了,所...
閱讀 2397·2021-10-09 09:44
閱讀 2132·2021-10-08 10:05
閱讀 3424·2021-07-26 23:38
閱讀 2991·2019-08-28 18:16
閱讀 812·2019-08-26 11:55
閱讀 1821·2019-08-23 18:29
閱讀 2035·2019-08-23 18:05
閱讀 1364·2019-08-23 17:02