欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring源碼解析之Configuration

 更新時(shí)間:2021年05月23日 14:30:50   作者:星夜孤帆  
今天帶大家來(lái)學(xué)習(xí)Java Spring相關(guān)知識(shí),文中對(duì)Configuration源碼介紹的非常詳細(xì),有非常多的圖文解說及代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們很有幫助,需要的朋友可以參考下

一、@Configuration

1.1 未加@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>

1.2 加上@Configuration

1.3 Cglib動(dòng)態(tài)代理

二、源碼跟蹤

2.1 AnnotationConfigApplicationContext

2.2 AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(Class<?>... annotatedClasses)

2.3 AbstractApplicationContext#refresh()

@Override
	public void refresh() throws BeansException, IllegalStateException {
		// 同步,線程安全; 防止 fresh還沒結(jié)束  就又進(jìn)入改方法 導(dǎo)致容器初始化錯(cuò)亂
		synchronized (this.startupShutdownMonitor) {
			// 準(zhǔn)備刷新 記錄開始時(shí)間  設(shè)置幾個(gè)標(biāo)志位  驗(yàn)證環(huán)境屬性
			prepareRefresh();
 
			// 告訴子類刷新內(nèi)部bean工廠  創(chuàng)建BeanFactory  并且獲取BeanDefinition的定義信息
			/**
			 *	obtainFreshBeanFactory();方法
			 *		解析為一個(gè)個(gè)beanDefinition 放在我們beanDefinitionMap中管理起來(lái)
			 *  1. refreshBeanFactory(); 核心方法
			 * 		AbstractRefreshableApplicationContext#refreshBeanFactory()
			 * 		創(chuàng)建DefaultListableBeanFactory 并設(shè)置屬性
			 * 		加載BeanFactory; 根據(jù)不同的類型,調(diào)用不同的方法
			 * 			org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)
			 */
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 
			// 準(zhǔn)備在這種情況下使用的bean工廠  向beanFactory中設(shè)置一些屬性  。對(duì)BeanFactory 進(jìn)行各種功能填充
			prepareBeanFactory(beanFactory);
 
			try {
				// 允許在上下文 的子類中對(duì)bean工廠進(jìn)行后處理  由子類去實(shí)現(xiàn); 主要是自定義去使用
				postProcessBeanFactory(beanFactory);
 
				// 第5步 【BeanFactoryPostProcessors ;bean工廠后置處理器】調(diào)用我們的bean工廠后置處理器 (所有實(shí)現(xiàn)接口BeanFactoryPostProcessor接口的)
				//		主要是
				// 		會(huì)在此將class掃描成BeanDefinition 并注冊(cè)bean 到一個(gè)BeanDefinitionMap中 這個(gè)過程使用到代理
				//BeanFactoryPostProcessor 可以 用于容器完成初始化()
				// 此處可以 還沒有實(shí)例化Bean之前讀取Bean的信息,并作出一些修改。
				// 例如修改Bean的屬性,修改Bean的scope等
				invokeBeanFactoryPostProcessors(beanFactory);
 
				//https://blog.csdn.net/caihaijiang/article/details/35552859
				// 【BeanPostProcessors ;bean后置處理器】 注冊(cè)BeanPostProcessor
				// BeanPostProcessor是Bean的后置處理器,
				// 在Bean的初始化方法[InitializingBean 以及init-method]前,后執(zhí)行。
				registerBeanPostProcessors(beanFactory);
 
				// 為上下文初始化Message 源, 即不同語(yǔ)言的消息體, 國(guó)際化處理 i18n
				initMessageSource();
 
				// 初始化事件傳播器
				//初始化應(yīng)用消息廣播器, 并放入"applicationEventMulticaster" bean 中
				initApplicationEventMulticaster();
 
				// 擴(kuò)展的一個(gè)實(shí)現(xiàn) ,留給子類來(lái)初始化其它的Bean。如springboot內(nèi)嵌的tomcat在這個(gè)階段完成
				onRefresh();
 
				// 注冊(cè)監(jiān)聽器
				// 在所有注冊(cè)的bean 中查找Listener bean , 注冊(cè)到消息廣播報(bào)中
				registerListeners();
 
				/**第11步
					對(duì)于非抽象類、非延遲初始化的單例bean,
					在spring容器啟動(dòng)的時(shí)候調(diào)用getBean方法來(lái)實(shí)例化bean, 并進(jìn)行相關(guān)初始化工作,
					getBean方法最終調(diào)用AbstractAutowireCapableBeanFactory.doCreateBean方法
				 */
				// 在創(chuàng)建BeanFactory的過程中,BeanDefinition注冊(cè)到了BeanFactory中的一個(gè)ConCurretHashMap對(duì)象中
				// 以BeanName為key,BeanDefinition為value ; 實(shí)例化所有剩余的(非延遲初始化)單例。
				finishBeanFactoryInitialization(beanFactory);
 
				// 第12步 最后一步:發(fā)布相應(yīng)的事件。
				//完成刷新過程, 通知生命周期處現(xiàn)器lifecycleProcessor 刷新過程, 同時(shí)發(fā)出ContextRefreshEvent 通知?jiǎng)e人
				finishRefresh();
			}
 
			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}
 
				// 第13步 銷毀以創(chuàng)建的Bean
				destroyBeans();
 
				//取消refresh操作,重置容器的同步標(biāo)識(shí)
				cancelRefresh(ex);
 
				// Propagate exception to caller.
				throw ex;
			}
 
			finally {
				resetCommonCaches();
			}
		}
	}

2.4 AbstractApplicationContext#invokeBeanFactoryPostProcessors

2.5 PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
 
		Set<String> processedBeans = new HashSet<>();
 
		// 對(duì)BeanDefinitionRegistry 類型的處理
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			// 用于存放BeanDefinitionRegistryPostProcessor
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
 
			// 遍歷所有的beanFactoryPostProcessors,將BeanDefinitionRegistryPostProcessor和普通BeanFactoryPostProcessor區(qū)分開
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					/**
						對(duì)于BeanDefinitionRegistryPostProcessor 類型, 在BeanFactoryPostProcessor 的
						基礎(chǔ)上還有自己定義的方法,需要先調(diào)用
					 */
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					// 記錄常規(guī)BeanFactoryPostProcessor
					regularPostProcessors.add(postProcessor);
				}
			}
 
			/**
				不要在這里初始化FactoryBeans: 我們需要保留所有常規(guī)bean未初始化,讓bean工廠后處理器應(yīng)用到它們!
				BeanDefinitionRegistryPostProcessors之間的分離實(shí)現(xiàn)排好序,點(diǎn)好,等等。
				獲取spring配置文件中定義的所有實(shí)現(xiàn)BeanFactoryPostProcessor接口的bean,然后根據(jù)優(yōu)先級(jí)進(jìn)行排序
			 */
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
 
			// 首先,調(diào)用實(shí)現(xiàn)優(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),調(diào)用實(shí)現(xiàn)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.
			// 調(diào)用ConfigurationClassPostProcessor#postProcessBeanFactory增強(qiáng)配置類
			// 通過cglib生成增強(qiáng)類
			// 設(shè)置beanDefinition的beanClass為增強(qiáng)類,讓@Bean生成的bean是單例
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}
 
		else {
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}
 
		// BeanFactoryPostProcessor.class類型
		// 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í)現(xiàn)BeanFactoryPostProcessor類的類名稱
 
		// 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類型
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				// 為Ordered類型
				orderedPostProcessorNames.add(ppName);
			}
			else {
				// 這個(gè)就是我們當(dāng)前需要關(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();
	}

2.6 PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

2.7 ConfigurationClassPostProcessor#postProcessBeanFactory

2.8 ConfigurationClaassPostProcessor#enhanceConfigurationClasses

public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
		Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
		for (String beanName : beanFactory.getBeanDefinitionNames()) {
			BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
			// 判斷是否是一個(gè)全注解類
			// 掃描是全注解類?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注解的類生成增強(qiáng)類
					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)修改beanDefinition的BeanClass屬性,
						// 在bean實(shí)例化階段,會(huì)利用反射技術(shù)將beanClass屬性對(duì)應(yīng)的類實(shí)例化出來(lái)
						// 所以最終實(shí)例化出來(lái)的@Configuration bean是一個(gè)代理類的實(shí)例
						beanDef.setBeanClass(enhancedClass);
					}
				}
			}
			catch (Throwable ex) {
				throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
			}
		}

2.9 ConfigurationClassUtils#checkConfigurationClassCandidate

1.在ConfigurationClassUtils類中的checkConfigurationClassCandidate標(biāo)記是Full @Configuration還是lite @Bean mode

2.通過"full".equals(configClassAttr)判斷是否是全類注解是全注解

3.則將beandefinition放入map中configBeanDefs.put

4.遍歷這個(gè)map

5.使用cglib技術(shù)為配置類生成一個(gè)enhancedClass

6.通過enhancer.enhance進(jìn)行cglib代理,為@Configuration注解的類生成增強(qiáng)類

7.再通過beanDef.setBeanClass(enhancedClass)修改beanDefinition的BeanClass屬性,在bean實(shí)例化階段,會(huì)利用反射技術(shù)將beanClass屬性對(duì)應(yīng)的類實(shí)例化出來(lái),所以最終實(shí)例化出來(lái)的@Configuration bean是一個(gè)代理類的實(shí)例

使用了@Configuration注解的類,屬于Full @Configuration。@Configuration類允許通過調(diào)用同一類中的其他@Bean方法來(lái)定義bean之間的依賴關(guān)系,保證@Bean的對(duì)象作用域受到控制,避免多例。

@Configuration類中的@Bean地方會(huì)被CGLIB進(jìn)行代理。Spring會(huì)攔截該方法的執(zhí)行,在默認(rèn)單例情況下,容器中只有一個(gè)Bean,所以我們多次調(diào)用user()方法,獲取的都是同一個(gè)對(duì)象。

對(duì)于@Configuration注解的類中@Bean標(biāo)記的方法,返回的都是一個(gè)bean,在增強(qiáng)的方法中,Spring會(huì)先去容器中查看一下是否有這個(gè)bean的實(shí)例了,如果有了的話,就返回已有對(duì)象,沒有的話就創(chuàng)建一個(gè),然后放到容器中。

2.10 ConfigurationClassEnhancer#enhance

2.11 ConfigurationClassEnhancer#newEnhancer

2.12 ConfigurationClassEnhancer#CallBacks

2.13 ConfigurationClassEnhancer#intercept

2.13.1 ConfigurationClassEnhancer#isCurrentlyInvokedFactoryMethod

2.14 ConfigurationClassEnhancer#resolveBeanReference

	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);
				}
			}
		}

三、總結(jié)

  •  lite @Bean mode :當(dāng)@Bean方法在沒有使用@Configuration注解的類中聲明時(shí)稱之為lite @Bean mode
  • Full @Configuration:如果@Bean方法在使用@Configuration注解的類中聲明時(shí)稱之為Full @Configuration

Full @Configuration中的@Bean方法會(huì)被CGLIB所代理,而 lite @Bean mode中的@Bean方法不會(huì)被CGLIB代理

@Configuration注解作用

1.告訴spring這是一個(gè)配置類,相當(dāng)于spring的xml配置文件

2.被@Configuration 注解的類,會(huì)被cglib代理進(jìn)行增強(qiáng)

3.@Configuration類允許通過調(diào)用同一類中的其他@Bean方法來(lái)定義bean之間的依賴關(guān)系,保證@Bean的對(duì)象作用域受到控制,避免多例

@Configuration注解底層是如何實(shí)現(xiàn)的,通過源碼咱們可以反推并總結(jié)為以下幾點(diǎn):

1.Spring首先會(huì)獲取到所有的beanDefenition

2.ConfigurationClassUtils類中checkConfigurationClassCandidate方法判斷是Full @Configuration還是lite @Bean mode

3.通過ConfigurationClassPostProcessor后置處理器遍歷所有的beanDefenition

4.將標(biāo)記了Full @Configuration模式的beanDefenition,會(huì)對(duì)這個(gè)類進(jìn)行cglib代理,生成一個(gè)代理類,并把這個(gè)類設(shè)置到BeanDefenition的Class屬性中

5.配置類會(huì)被CGLIB增強(qiáng)(生成代理對(duì)象),放進(jìn)IoC容器內(nèi)的是代理

6.對(duì)于內(nèi)部類是沒有限制的:可以是Full模式或者Lite模式

7.配置類內(nèi)部可以通過方法調(diào)用來(lái)處理依賴,并且能夠保證是同一個(gè)實(shí)例,都指向IoC內(nèi)的那個(gè)單例

8.需要用這個(gè)Bean實(shí)例的時(shí)候,從這個(gè)Class屬性中拿到的Class對(duì)象進(jìn)行反射,最終反射出來(lái)的是代理增強(qiáng)后的類

9.通過@Configuration標(biāo)注類的Bean,Spring會(huì)先去容器中查看是否有這個(gè)Bean實(shí)例,如果有就返回已有的對(duì)象,沒有就創(chuàng)建一個(gè),然后放到容器中

到此這篇關(guān)于Spring源碼解析之Configuration的文章就介紹到這了,更多相關(guān)Configuration源碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于XML的MyBatis的環(huán)境搭建過程詳解(IDEA)

    基于XML的MyBatis的環(huán)境搭建過程詳解(IDEA)

    這篇文章主要介紹了基于XML的MyBatis的環(huán)境搭建過程詳解(IDEA),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • 一個(gè)applicationContext 加載錯(cuò)誤導(dǎo)致的阻塞問題及解決方法

    一個(gè)applicationContext 加載錯(cuò)誤導(dǎo)致的阻塞問題及解決方法

    這篇文章主要介紹了一個(gè)applicationContext 加載錯(cuò)誤導(dǎo)致的阻塞問題及解決方法,需要的朋友可以參考下
    2018-11-11
  • 淺談Mybatis傳參類型如何確定

    淺談Mybatis傳參類型如何確定

    最近有小伙伴在討論#{}與${}的區(qū)別時(shí),有提到#{}是用字符串進(jìn)行替換,本文主要介紹了mapper接口中不同的參數(shù)類型,最終拼接sql中是如何進(jìn)行替換的,感興趣的可以了解一下
    2021-10-10
  • Spring5中的WebClient使用方法詳解

    Spring5中的WebClient使用方法詳解

    這篇文章主要給大家介紹了關(guān)于Spring5中WebClient使用方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring5具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Java中LinkedHashSet、LinkedHashMap源碼詳解

    Java中LinkedHashSet、LinkedHashMap源碼詳解

    這篇文章主要介紹了Java中LinkedHashSet、LinkedHashMap源碼詳解,LinkedHashMap是一個(gè)以雙向鏈表的方式將Entry節(jié)點(diǎn)鏈接起來(lái)的HashMap子類,它在HashMap的基礎(chǔ)上實(shí)現(xiàn)了更多的功能,具有順序存儲(chǔ)和遍歷的特性,需要的朋友可以參考下
    2023-09-09
  • springboot的maven多模塊混淆jar包的實(shí)現(xiàn)方法

    springboot的maven多模塊混淆jar包的實(shí)現(xiàn)方法

    springboot可以使用proguard-maven-plugin 這個(gè)插件 在 pom.xml 中自定義proguard 的指令,本文基于 springboot + maven + proguard 的maven多模塊架構(gòu)進(jìn)行代碼混淆,需要的朋友可以參考下
    2024-03-03
  • logback日志輸出格式設(shè)置方式

    logback日志輸出格式設(shè)置方式

    這篇文章主要介紹了logback日志輸出格式設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • java使用es查詢的示例代碼

    java使用es查詢的示例代碼

    本篇文章主要介紹了java使用es查詢的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2018-01-01
  • SpringMVC框架post提交數(shù)據(jù)庫(kù)出現(xiàn)亂碼解決方案

    SpringMVC框架post提交數(shù)據(jù)庫(kù)出現(xiàn)亂碼解決方案

    這篇文章主要介紹了SpringMVC框架post提交數(shù)據(jù)庫(kù)出現(xiàn)亂碼解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java Swing組件編程之JTable表格用法實(shí)例詳解

    Java Swing組件編程之JTable表格用法實(shí)例詳解

    這篇文章主要介紹了Java Swing組件編程之JTable表格用法,結(jié)合實(shí)例形式詳細(xì)分析了Swing組件中JTable表格的常見定義與使用方法,需要的朋友可以參考下
    2017-11-11

最新評(píng)論