- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) >
- Spring源碼解析之Configuration
<!--logback-test.xml,配置不打印日志--> <?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/base.xml" /> <logger name="org.springframework" level="OFF"/> </configuration>
@Override public void refresh() throws BeansException, IllegalStateException { // 同步,線(xiàn)程安全; 防止 fresh還沒(méi)結束 就又進(jìn)入改方法 導致容器初始化錯亂 synchronized (this.startupShutdownMonitor) { // 準備刷新 記錄開(kāi)始時(shí)間 設置幾個(gè)標志位 驗證環(huán)境屬性 prepareRefresh(); // 告訴子類(lèi)刷新內部bean工廠(chǎng) 創(chuàng )建BeanFactory 并且獲取BeanDefinition的定義信息 /** * obtainFreshBeanFactory();方法 * 解析為一個(gè)個(gè)beanDefinition 放在我們beanDefinitionMap中管理起來(lái) * 1. refreshBeanFactory(); 核心方法 * AbstractRefreshableApplicationContext#refreshBeanFactory() * 創(chuàng )建DefaultListableBeanFactory 并設置屬性 * 加載BeanFactory; 根據不同的類(lèi)型,調用不同的方法 * org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory) */ ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 準備在這種情況下使用的bean工廠(chǎng) 向beanFactory中設置一些屬性 。對BeanFactory 進(jìn)行各種功能填充 prepareBeanFactory(beanFactory); try { // 允許在上下文 的子類(lèi)中對bean工廠(chǎng)進(jìn)行后處理 由子類(lèi)去實(shí)現; 主要是自定義去使用 postProcessBeanFactory(beanFactory); // 第5步 【BeanFactoryPostProcessors ;bean工廠(chǎng)后置處理器】調用我們的bean工廠(chǎng)后置處理器 (所有實(shí)現接口BeanFactoryPostProcessor接口的) // 主要是 // 會(huì )在此將class掃描成BeanDefinition 并注冊bean 到一個(gè)BeanDefinitionMap中 這個(gè)過(guò)程使用到代理 //BeanFactoryPostProcessor 可以 用于容器完成初始化() // 此處可以 還沒(méi)有實(shí)例化Bean之前讀取Bean的信息,并作出一些修改。 // 例如修改Bean的屬性,修改Bean的scope等 invokeBeanFactoryPostProcessors(beanFactory); //https://blog.csdn.net/caihaijiang/article/details/35552859 // 【BeanPostProcessors ;bean后置處理器】 注冊BeanPostProcessor // BeanPostProcessor是Bean的后置處理器, // 在Bean的初始化方法[InitializingBean 以及init-method]前,后執行。 registerBeanPostProcessors(beanFactory); // 為上下文初始化Message 源, 即不同語(yǔ)言的消息體, 國際化處理 i18n initMessageSource(); // 初始化事件傳播器 //初始化應用消息廣播器, 并放入"applicationEventMulticaster" bean 中 initApplicationEventMulticaster(); // 擴展的一個(gè)實(shí)現 ,留給子類(lèi)來(lái)初始化其它的Bean。如springboot內嵌的tomcat在這個(gè)階段完成 onRefresh(); // 注冊監聽(tīng)器 // 在所有注冊的bean 中查找Listener bean , 注冊到消息廣播報中 registerListeners(); /**第11步 對于非抽象類(lèi)、非延遲初始化的單例bean, 在spring容器啟動(dòng)的時(shí)候調用getBean方法來(lái)實(shí)例化bean, 并進(jìn)行相關(guān)初始化工作, getBean方法最終調用AbstractAutowireCapableBeanFactory.doCreateBean方法 */ // 在創(chuàng )建BeanFactory的過(guò)程中,BeanDefinition注冊到了BeanFactory中的一個(gè)ConCurretHashMap對象中 // 以BeanName為key,BeanDefinition為value ; 實(shí)例化所有剩余的(非延遲初始化)單例。 finishBeanFactoryInitialization(beanFactory); // 第12步 最后一步:發(fā)布相應的事件。 //完成刷新過(guò)程, 通知生命周期處現器lifecycleProcessor 刷新過(guò)程, 同時(shí)發(fā)出ContextRefreshEvent 通知別人 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // 第13步 銷(xiāo)毀以創(chuàng )建的Bean destroyBeans(); //取消refresh操作,重置容器的同步標識 cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { resetCommonCaches(); } } }
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { Set<String> processedBeans = new HashSet<>(); // 對BeanDefinitionRegistry 類(lèi)型的處理 if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); // 用于存放BeanDefinitionRegistryPostProcessor List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); // 遍歷所有的beanFactoryPostProcessors,將BeanDefinitionRegistryPostProcessor和普通BeanFactoryPostProcessor區分開(kāi) for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; /** 對于BeanDefinitionRegistryPostProcessor 類(lèi)型, 在BeanFactoryPostProcessor 的 基礎上還有自己定義的方法,需要先調用 */ registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { // 記錄常規BeanFactoryPostProcessor regularPostProcessors.add(postProcessor); } } /** 不要在這里初始化FactoryBeans: 我們需要保留所有常規bean未初始化,讓bean工廠(chǎng)后處理器應用到它們! BeanDefinitionRegistryPostProcessors之間的分離實(shí)現排好序,點(diǎn)好,等等。 獲取spring配置文件中定義的所有實(shí)現BeanFactoryPostProcessor接口的bean,然后根據優(yōu)先級進(jìn)行排序 */ List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // 首先,調用實(shí)現優(yōu)先排序的BeanDefinitionRegistryPostProcessors String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // PriorityOrdered.class 優(yōu)先排序 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // 接下來(lái),調用實(shí)現Ordered的BeanDefinitionRegistryPostProcessors postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // Ordered.class if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // 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)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } // Now, invoke the postProcessBeanFactory callback of all processors handled so far. // 調用ConfigurationClassPostProcessor#postProcessBeanFactory增強配置類(lèi) // 通過(guò)cglib生成增強類(lèi) // 設置beanDefinition的beanClass為增強類(lèi),讓@Bean生成的bean是單例 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // BeanFactoryPostProcessor.class類(lèi)型 // 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); // 篩選出bean工程中存在的所有實(shí)現BeanFactoryPostProcessor類(lèi)的類(lèi)名稱(chēng) // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip - already processed in first phase above // 已經(jīng)存在了,不再處理 } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 為PriorityOrdered類(lèi)型 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { // 為Ordered類(lèi)型 orderedPostProcessorNames.add(ppName); } else { // 這個(gè)就是我們當前需要關(guān)心的PostProcessors //nonOrderedPostProcessors添加的不是bean實(shí)例,而是BeanDefinition nonOrderedPostProcessorNames.add(ppName); } } // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // Next, invoke the BeanFactoryPostProcessors that implement Ordered. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // Finally, invoke all other BeanFactoryPostProcessors. List<BeanFactoryPostProcessor> 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(); }
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) { Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>(); for (String beanName : beanFactory.getBeanDefinitionNames()) { BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName); // 判斷是否是一個(gè)全注解類(lèi) // 掃描是全注解類(lèi)?full和lite的關(guān)系 if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) { if (!(beanDef instanceof AbstractBeanDefinition)) { throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" + beanName + "' since it is not stored in an AbstractBeanDefinition subclass"); } else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) { logger.info("Cannot enhance @Configuration bean definition '" + beanName + "' since its singleton instance has been created too early. The typical cause " + "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " + "return type: Consider declaring such methods as 'static'."); } // 是全注解,需要代理,添加到configBeanDefs中 configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef); } } if (configBeanDefs.isEmpty()) { // nothing to enhance -> return immediately return; } ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer(); // 遍歷這個(gè)map for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) { AbstractBeanDefinition beanDef = entry.getValue(); // If a @Configuration class gets proxied, always proxy the target class beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE); try { // Set enhanced subclass of the user-specified bean class Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader); if (configClass != null) { // 進(jìn)行cglib代理,為@Configuration注解的類(lèi)生成增強類(lèi) Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader); if (configClass != enhancedClass) { if (logger.isTraceEnabled()) { logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " + "enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName())); } // 再通過(guò)beanDef.setBeanClass(enhancedClass)修改beanDefinition的BeanClass屬性, // 在bean實(shí)例化階段,會(huì )利用反射技術(shù)將beanClass屬性對應的類(lèi)實(shí)例化出來(lái) // 所以最終實(shí)例化出來(lái)的@Configuration bean是一個(gè)代理類(lèi)的實(shí)例 beanDef.setBeanClass(enhancedClass); } } } catch (Throwable ex) { throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex); } }
1.在ConfigurationClassUtils類(lèi)中的checkConfigurationClassCandidate標記是Full @Configuration還是lite @Bean mode
2.通過(guò)"full".equals(configClassAttr)判斷是否是全類(lèi)注解是全注解
3.則將beandefinition放入map中configBeanDefs.put
4.遍歷這個(gè)map
5.使用cglib技術(shù)為配置類(lèi)生成一個(gè)enhancedClass
6.通過(guò)enhancer.enhance進(jìn)行cglib代理,為@Configuration注解的類(lèi)生成增強類(lèi)
7.再通過(guò)beanDef.setBeanClass(enhancedClass)修改beanDefinition的BeanClass屬性,在bean實(shí)例化階段,會(huì )利用反射技術(shù)將beanClass屬性對應的類(lèi)實(shí)例化出來(lái),所以最終實(shí)例化出來(lái)的@Configuration bean是一個(gè)代理類(lèi)的實(shí)例
使用了@Configuration注解的類(lèi),屬于Full @Configuration。@Configuration類(lèi)允許通過(guò)調用同一類(lèi)中的其他@Bean方法來(lái)定義bean之間的依賴(lài)關(guān)系,保證@Bean的對象作用域受到控制,避免多例。
@Configuration類(lèi)中的@Bean地方會(huì )被CGLIB進(jìn)行代理。Spring會(huì )攔截該方法的執行,在默認單例情況下,容器中只有一個(gè)Bean,所以我們多次調用user()方法,獲取的都是同一個(gè)對象。
對于@Configuration注解的類(lèi)中@Bean標記的方法,返回的都是一個(gè)bean,在增強的方法中,Spring會(huì )先去容器中查看一下是否有這個(gè)bean的實(shí)例了,如果有了的話(huà),就返回已有對象,沒(méi)有的話(huà)就創(chuàng )建一個(gè),然后放到容器中。
private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs, ConfigurableBeanFactory beanFactory, String beanName) { // The user (i.e. not the factory) is requesting this bean through a call to // the bean method, direct or indirect. The bean may have already been marked // as 'in creation' in certain autowiring scenarios; if so, temporarily set // the in-creation status to false in order to avoid an exception. // 判斷他是否正在創(chuàng )建 boolean alreadyInCreation = beanFactory.isCurrentlyInCreation(beanName); try { if (alreadyInCreation) { beanFactory.setCurrentlyInCreation(beanName, false); } boolean useArgs = !ObjectUtils.isEmpty(beanMethodArgs); if (useArgs && beanFactory.isSingleton(beanName)) { // Stubbed null arguments just for reference purposes, // expecting them to be autowired for regular singleton references? // A safe assumption since @Bean singleton arguments cannot be optional... for (Object arg : beanMethodArgs) { if (arg == null) { useArgs = false; break; } } } Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) : beanFactory.getBean(beanName)); if (!ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) { // Detect package-protected NullBean instance through equals(null) check if (beanInstance.equals(null)) { if (logger.isDebugEnabled()) { logger.debug(String.format("@Bean method %s.%s called as bean reference " + "for type [%s] returned null bean; resolving to null value.", beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(), beanMethod.getReturnType().getName())); } beanInstance = null; } else { String msg = String.format("@Bean method %s.%s called as bean reference " + "for type [%s] but overridden by non-compatible bean instance of type [%s].", beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(), beanMethod.getReturnType().getName(), beanInstance.getClass().getName()); try { BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName); msg += " Overriding bean of same name declared in: " + beanDefinition.getResourceDescription(); } catch (NoSuchBeanDefinitionException ex) { // Ignore - simply no detailed message then. } throw new IllegalStateException(msg); } } Method currentlyInvoked = SimpleInstantiationStrategy.getCurrentlyInvokedFactoryMethod(); if (currentlyInvoked != null) { String outerBeanName = BeanAnnotationHelper.determineBeanNameFor(currentlyInvoked); beanFactory.registerDependentBean(beanName, outerBeanName); } return beanInstance; } finally { if (alreadyInCreation) { beanFactory.setCurrentlyInCreation(beanName, true); } } }
Full @Configuration
中的@Bean
方法會(huì )被CGLIB所代理,而 lite @Bean mode
中的@Bean
方法不會(huì )被CGLIB代理
@Configuration注解作用
1.告訴spring這是一個(gè)配置類(lèi),相當于spring的xml配置文件
2.被@Configuration 注解的類(lèi),會(huì )被cglib代理進(jìn)行增強
figuration類(lèi)允許通過(guò)調用同一類(lèi)中的其他@Bean方法來(lái)定義bean之間的依賴(lài)關(guān)系,保證@Bean的對象作用域受到控制,避免多例
@Configuration注解底層是如何實(shí)現的,通過(guò)源碼咱們可以反推并總結為以下幾點(diǎn):
1.Spring首先會(huì )獲取到所有的beanDefenition
2.ConfigurationClassUtils類(lèi)中checkConfigurationClassCandidate方法判斷是Full @Configuration還是lite @Bean mode
3.通過(guò)ConfigurationClassPostProcessor后置處理器遍歷所有的beanDefenition
4.將標記了Full @Configuration模式的beanDefenition,會(huì )對這個(gè)類(lèi)進(jìn)行cglib代理,生成一個(gè)代理類(lèi),并把這個(gè)類(lèi)設置到BeanDefenition的Class屬性中
5.配置類(lèi)會(huì )被CGLIB增強(生成代理對象),放進(jìn)IoC容器內的是代理
6.對于內部類(lèi)是沒(méi)有限制的:可以是Full模式或者Lite模式
7.配置類(lèi)內部可以通過(guò)方法調用來(lái)處理依賴(lài),并且能夠保證是同一個(gè)實(shí)例,都指向IoC內的那個(gè)單例
8.需要用這個(gè)Bean實(shí)例的時(shí)候,從這個(gè)Class屬性中拿到的Class對象進(jìn)行反射,最終反射出來(lái)的是代理增強后的類(lèi)
9.通過(guò)@Configuration標注類(lèi)的Bean,Spring會(huì )先去容器中查看是否有這個(gè)Bean實(shí)例,如果有就返回已有的對象,沒(méi)有就創(chuàng )建一個(gè),然后放到容器中
到此這篇關(guān)于Spring源碼解析之Configuration的文章就介紹到這了,更多相關(guān)Configuration源碼內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站