<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Spring源碼解析之@Configuration

      @Configuration簡介

      用于標(biāo)識一個類為配置類,與xml配置效果類似

      用法簡介

      public class TestApplication {
      
          public static void main(String args[]) {
              AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
      
          }
      }
      
      @Configuration
      public class AppConfig {
      
      	@Bean
      	public A a(){
      		return new A();
      	}
      	@Bean
      	public B b(){
      		return new B();
      	}
      } 
      
      
      
      
      public class A {
      
      	public A(){
      		System.out.println("Call A constructor");
      	}
      }
      
      
      
      public class B {
      
      	public B(){
      		System.out.println("Call B constructor");
      	}
      }
      

      上面的例子應(yīng)該是@Configuration最普遍一種使用場景了,在@Configuration class下面配置@Bean method,用于想Spring Ioc容器注入bean.但其實我們把AppConfig的@Configuration注解去掉,對應(yīng)的Bean也是可以被注入到容器中去的。

      那么問題來了@Configuration到底有什么作用?

      我們給AppConfig改寫一下,如下:

      @Configuration
      @EnableAspectJAutoProxy
      public class AppConfig {
      
         @Bean
         public A a(){
            b();
            return new A();
         }
         @Bean
         public B b(){
            return new B();
         }
      

      再去執(zhí)行TestApplication#main,那么執(zhí)行結(jié)果會是什么樣呢?

      Call A constructor
      Call B constructor
      

      嗯哼?按照J(rèn)ava的語法,B的構(gòu)造函數(shù)應(yīng)該是被調(diào)用了兩次???為什么只有輸出一句Call B constructor?

      這其實就是@Configuration再發(fā)揮作用啦,不信你去掉@Configuration,再去運行一下,就會發(fā)現(xiàn)B的構(gòu)造函數(shù)被執(zhí)行了兩次。

      官方給出了這樣一段解釋對于被@Configuration注解的類

      In common scenarios, @Beanmethods are to be declared within@Configurationclasses, ensuring that “full” mode is always used and that cross-method references therefore get redirected to the container’s lifecycle management.

      在一般情況下,@Bean method 是被聲明在@Configuration類中的,以確保 full mode總是被使用,并且跨方法的引用會被重定向到容器生命周期管理。

      怎么理解呢?

      原來Spring將被@Configuration注解的配置類定義為full configuration, 而將沒有被@Configuration注解的配置類定義為lite configuration。full configuration能重定向從跨方法的引用,從而保證上述代碼中的b bean是一個單例.

      源碼中是如何實現(xiàn)@Configuration語意

      public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
         /**
          * 調(diào)用無參構(gòu)造函數(shù),實例化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner
          * 同時會調(diào)用父類GenericApplicationContext無參構(gòu)造函數(shù)實例化一個關(guān)鍵的工廠DefaultListableBeanFactory
          * 同時還會注冊一些開天辟地的后置處理器到beanDefinitionMap,這些后置處理器有bean工廠后置處理器;有bean后置處理器
          */
         this();
         //將componentClasses注冊到beanDefinitionMap集合中去
         register(componentClasses);
        
         refresh();
      }
      

      跟蹤refresh()

      @Override
      public void refresh() throws BeansException, IllegalStateException {
         synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();
      
            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      
            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);
      
            try {
               // Allows post-processing of the bean factory in context subclasses.
               //供上下文(Context)子類繼承,允許在這里后置處理bean factory
               postProcessBeanFactory(beanFactory);
      
               // Invoke factory processors registered as beans in the context.
               //按順序調(diào)用BeanFactoryPostProcessor,這里的按順序僅實現(xiàn)了PriorityOrdered和Ordered的語意,未實現(xiàn)@Order注解的語意
               //通過調(diào)用ConfigurationConfigPostProcessor#postProcessBeanDefinitionRegistry
               //解析@Configuration配置類,將自定義的BeanFactoryPostProcessor、BeanPostProcessor注冊到beanDefinitionMap
               //接著實例化所有(包括開天辟地)的BeanFactoryPostProcessor,然后再調(diào)用BeanFactoryPostProcessor#postProcessBeanFactory
               invokeBeanFactoryPostProcessors(beanFactory);
      
               // Register bean processors that intercept bean creation.
               //按順序?qū)eanPostProcessor實例化成bean并注冊到beanFactory的beanPostProcessors,
               //這里的按順序僅實現(xiàn)了PriorityOrdered和Ordered的語意,未實現(xiàn)@Order注解的語意
               //因為BeanPostProcessor要在普通bean初始化()前后被調(diào)用,所以需要提前完成實例化并注冊到beanFactory的beanPostProcessors
               registerBeanPostProcessors(beanFactory);
      
               // Initialize message source for this context.
               //注冊國際化相關(guān)的Bean
               initMessageSource();
      
               // Initialize event multicaster for this context.
               //為上下文注冊應(yīng)用事件廣播器(用于ApplicationEvent的廣播),如果有自定義則使用自定義的,如果沒有則內(nèi)部實例化一個
               initApplicationEventMulticaster();
      
               // Initialize other special beans in specific context subclasses.
               onRefresh();
      
               // Check for listener beans and register them.
               //注冊所有(靜態(tài)、動態(tài))的listener,并廣播earlyApplicationEvents
               registerListeners();
      
               // Instantiate all remaining (non-lazy-init) singletons.
               //實例化用戶自定義的普通單例Bean(非開天辟地的、非后置處理器)
               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();
            }
         }
      }
      

      跟蹤invokeBeanFactoryPostProcessors(beanFactory)

      protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
         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()));
         }
      }
      

      跟蹤invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

      public static void invokeBeanFactoryPostProcessors(
      			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
      
      		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
      		Set<String> processedBeans = new HashSet<>();
      
      		if (beanFactory instanceof BeanDefinitionRegistry) {
      			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
      			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
      
      			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
      				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
      					BeanDefinitionRegistryPostProcessor registryProcessor =
      							(BeanDefinitionRegistryPostProcessor) postProcessor;
      					registryProcessor.postProcessBeanDefinitionRegistry(registry);
      					registryProcessors.add(registryProcessor);
      				}
      				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.
      			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
      
      			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
      			String[] postProcessorNames =
      					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      			for (String ppName : postProcessorNames) {
      				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
      					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
      					processedBeans.add(ppName);
      				}
      			}
      			sortPostProcessors(currentRegistryProcessors, beanFactory);
      			registryProcessors.addAll(currentRegistryProcessors);
      			//此處調(diào)用ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry,
      			//解析配置類,為配置中的bean定義生成對應(yīng)beanDefinition,并注入到registry的beanDefinitionMap
      			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      			currentRegistryProcessors.clear();
      
      			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
      			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      			for (String ppName : postProcessorNames) {
      				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.
      			//調(diào)用ConfigurationClassPostProcessor#postProcessBeanFactory增強配置類(通過cglib生成增強類,load到j(luò)vm內(nèi)存,
      			//設(shè)置beanDefinition的beanClass為增強類)
      			//為什么要增強配置類?主要是為了讓@Bean生成的bean是單例,
      			invokeBeanFactoryPostProcessors(registryProcessors, 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<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
      			}
      			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(priorityOrderedPostProcessors, beanFactory);
      		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
      
      		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
      		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
      		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<>(nonOrderedPostProcessorNames.size());
      		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();
      	}
      

      跟蹤invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);

      private static void invokeBeanFactoryPostProcessors(
            Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
      
         for (BeanFactoryPostProcessor postProcessor : postProcessors) {
            postProcessor.postProcessBeanFactory(beanFactory);
         }
      }
      

      跟蹤ConfigurationClassPostProcessor#postProcessBeanFactory

      @Override
      public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
         int factoryId = System.identityHashCode(beanFactory);
         if (this.factoriesPostProcessed.contains(factoryId)) {
            throw new IllegalStateException(
                  "postProcessBeanFactory already called on this post-processor against " + beanFactory);
         }
         this.factoriesPostProcessed.add(factoryId);
         if (!this.registriesPostProcessed.contains(factoryId)) {
            // BeanDefinitionRegistryPostProcessor hook apparently not supported...
            // Simply call processConfigurationClasses lazily at this point then.
            processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
         }
         //為@Configuration注解的類生成增強類(如果有必要),并替換bd中的beanClass屬性,
         enhanceConfigurationClasses(beanFactory);
         beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
      }
      

      到了這一步謎底幾乎已經(jīng)揭曉了,@Configuration class是通過增強來實現(xiàn)它的語義的。通過增強把跨方法的引用調(diào)用重定向到Spring生命周期管理.我們近一步探索下這個enhanceConfigurationClasses方法

      public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
         Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
         for (String beanName : beanFactory.getBeanDefinitionNames()) {
            BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
            Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
            MethodMetadata methodMetadata = null;
            if (beanDef instanceof AnnotatedBeanDefinition) {
               methodMetadata = ((AnnotatedBeanDefinition) beanDef).getFactoryMethodMetadata();
            }
            if ((configClassAttr != null || methodMetadata != null) && beanDef instanceof AbstractBeanDefinition) {
               // Configuration class (full or lite) or a configuration-derived @Bean method
               // -> resolve bean class at this point...
               AbstractBeanDefinition abd = (AbstractBeanDefinition) beanDef;
               if (!abd.hasBeanClass()) {
                  try {
                     abd.resolveBeanClass(this.beanClassLoader);
                  }
                  catch (Throwable ex) {
                     throw new IllegalStateException(
                           "Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
                  }
               }
            }
            //在ConfigurationClassUtils.checkConfigurationClassCandidate方法中會標(biāo)記Configuration is full or lite
            if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {
               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.put(beanName, (AbstractBeanDefinition) beanDef);
            }
         }
         if (configBeanDefs.isEmpty()) {
            // nothing to enhance -> return immediately
            return;
         }
      
         ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
         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);
            // Set enhanced subclass of the user-specified bean class
            Class<?> configClass = beanDef.getBeanClass();
            //為@Configuration注解的類生成增強類
            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()));
               }
               beanDef.setBeanClass(enhancedClass);
            }
         }
      }
      

      看到有那么一句話Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);

      很明顯了,使用cglib技術(shù)為config class生成一個enhancedClass,再通過beanDef.setBeanClass(enhancedClass);修改beanDefinition的BeanClass屬性,在bean實例化階段,會利用反射技術(shù)將beanClass屬性對應(yīng)的類實例化出來,所以最終實例化出來的@Configuration bean是一個代理類的實例。這里稍微提一下為什么要使用cglib,而不是jdk動態(tài)代理,主要是因為jdk動態(tài)代理是基于接口的,而這里AppConfig并沒有實現(xiàn)任何接口,所以必須用cglib技術(shù)。

      總結(jié)

      被@Configuration 注解的類,是 full configuration class,該類會被增強(通過cglib),從而實現(xiàn)跨方法引用調(diào)用被重定向到Spring 生命周期管理,最終保證@Bean method生成的bean是一個單例。

      posted @ 2019-11-17 16:46  陳其苗  閱讀(4043)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 国产精品第一页中文字幕| 县级市| 国产精品大片中文字幕| 色综合色国产热无码一| 龙口市| 呦系列视频一区二区三区| 国产精品天干天干综合网| 亚洲欧洲∨国产一区二区三区| 人妻少妇精品中文字幕| 国产美女高潮流白浆视频| 国产自拍偷拍视频在线观看 | 亚洲国产精品成人精品无码区在线| 久久婷婷成人综合色综合| 国产成人亚洲无码淙合青草| A级毛片100部免费看| 礼泉县| 色综合久久久久综合体桃花网| 久久精品第九区免费观看| 国产无套内射又大又猛又粗又爽| 激情综合网激情综合网激情| 国产不卡一区二区精品| 亚洲中文无码永久免费| 亚洲国产成人久久77| 日韩精品亚洲不卡一区二区| 久久精品午夜视频| 成人午夜视频一区二区无码| 国产精品国产三级国产专业| ww污污污网站在线看com| 成全高清在线播放电视剧| 精品一区二区成人码动漫| 国产一区二区三区精品综合| 蜜臀av久久国产午夜福利软件| 久久综合色最新久久综合色| 大陆一级毛片免费播放| 蜜臀av黑人亚洲精品| 一区二区三区国产综合在线| 老司机性色福利精品视频| 午夜福利yw在线观看2020 | 精品国产一区二区三区麻豆| 男女激情一区二区三区| 亚洲AV无码破坏版在线观看|