国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

一起學SF框架系列5.4-模塊Beans-DefaultListableBeanFactory

這篇具有很好參考價值的文章主要介紹了一起學SF框架系列5.4-模塊Beans-DefaultListableBeanFactory。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

在生成ApplicationContext過程中,AbstractRefreshableApplicationContext.refreshBeanFactory()完成舊BeanFactory關閉,創(chuàng)建新的BeanFactory,即new DefaultListableBeanFactory(…)。然后bean實例化時調(diào)用本類的preInstantiateSingletons方法。

類作用

BeanFactory作用是初始化和管理普通bean,因此DefaultListableBeanFactory是實現(xiàn)框架核心功能(IoC)的核心類。

類關系圖

一起學SF框架系列5.4-模塊Beans-DefaultListableBeanFactory
DefaultListableBeanFactory類關系圖比較復雜,我們從頂向下梳理:

接口定義說明

AliasRegistry:頂層接口,別名注冊表接口,定義了管理bean的別名和名稱映射關系的基本方法,如注冊registerAlias(String name, String alias)、獲取(getAliases(String name))和銷毀(removeAlias(String alias))。

SingletonBeanRegistry:頂層接口,單實例bean注冊表接口,定義了管理單實例Bean的基本方法,如注冊(registerSingleton(String beanName, Object singletonObject))和獲?。╣etSingleton(String beanName)。

BeanFactory:頂層接口,定義了訪問bean容器中bean的基本方法,只包括get或判斷(如is、contain)類方法。完全不包括BeanFactory是如何初始化并管理bean的方法。從使用者來說,只是按需使用即可,不關注如何實現(xiàn)。

HierarchicalBeanFactory:繼承BeanFactory,僅提供訪問繼承關系BeanFactory的方法,包括etParentBeanFactory()和containsLocalBean(String name)(當前BeanFactory(不是父BeanFactory)是否包含名為name的bean)。

ListableBeanFactory:是BeanFactory接口擴展,定義通過枚舉其所有bean實例的方法來訪問bean,而不是通過getBean(String beanName)這種單個按名稱查找bean。

AutowireCapableBeanFactory:是BeanFactory接口擴展,定義具備自動裝配能力的BeanFactory的實現(xiàn)方法。

ConfigurableBeanFactory:定義普通配置模式下BeanFactory的實現(xiàn)方法,如解析bean配置和bean的初始化。

ConfigurableListableBeanFactory:繼承了接口ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory,并增加定義了分析和修改bean定義以及預實例化單實例bean的方法。

BeanDefinitionRegistry:BeanDefinition注冊表接口,定義對BeanDefinition(即bean的元數(shù)據(jù))進行管理的方法。

SimpleAliasRegistry

實現(xiàn)接口AliasRegistry(bean alias存取及相關操作)。

DefaultSingletonBeanRegistry

主要實現(xiàn)單實例bean的緩存池,包括bean依賴關系管理(關系注冊和銷毀)。本類方法大量采用了synchronized存取緩存池(集合)。
繼承于SimpleAliasRegistry,并實現(xiàn)接口SingletonBeanRegistry(單實例bean的存取及相關操作)

FactoryBeanRegistrySupport

單實例bean管理中用到的關于factoryBean的相關方法實現(xiàn)。

AbstractBeanFactory

AbstractBeanFactory主要實現(xiàn)ConfigurableBeanFactory接口功能。BeanFactory大多數(shù)功能在該類實現(xiàn),但核心方法createBean需在子類實現(xiàn)。

AbstractAutowireCapableBeanFactory

繼承AbstractBeanFactory,并實現(xiàn)接口AutowireCapableBeanFactory,即自動裝配相關功能在該類實現(xiàn)。
核心方法createBean在該類實現(xiàn)。

DefaultListableBeanFactory

繼承AbstractAutowireCapableBeanFactory,主要實現(xiàn)接口ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable。其中ConfigurableListableBeanFactory接口中的AutowireCapableBeanFactory, ConfigurableBeanFactory均在祖先類實現(xiàn)了,因此只需實現(xiàn)ListableBeanFactory接口方法。BeanDefinitionRegistry接口全部在這里實現(xiàn)。

類實現(xiàn)

DefaultListableBeanFactory繼承于AbstractAutowireCapableBeanFactory,大多數(shù)bean的創(chuàng)建、初始化等實現(xiàn)已在祖先類實現(xiàn)。本類主要實現(xiàn)BeanDefinitionRegistry接口和ListableBeanFactory接口。

DefaultListableBeanFactory(@Nullable BeanFactory parentBeanFactory)

DefaultListableBeanFactory構建類,實際構建在父類AbstractAutowireCapableBeanFactory完成,核心動作是動態(tài)生成子類的對象instantiationStrategy(CglibSubclassingInstantiationStrategy 用cgilib動態(tài)創(chuàng)建子類)。
DefaultListableBeanFactory構建代碼:

	public DefaultListableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
		super(parentBeanFactory);
	}

父類AbstractAutowireCapableBeanFactory構建代碼:

	public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
		this();
		setParentBeanFactory(parentBeanFactory);
	}
	public AbstractAutowireCapableBeanFactory() {
		super();
		ignoreDependencyInterface(BeanNameAware.class);
		ignoreDependencyInterface(BeanFactoryAware.class);
		ignoreDependencyInterface(BeanClassLoaderAware.class);
		//bean實例化器 
		this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();
	}

注1:CglibSubclassingInstantiationStrategy是Bean真正初始化類,詳見https://blog.csdn.net/davidwkx/article/details/131053503

preInstantiateSingletons

該方法是啟動過程中spring對單實例bean初始化的入口。

	@Override
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			//所有bean定義都統(tǒng)一成RootBeanDefinition 注1
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//非抽象類、非延遲加載且是Singleton的bean進行初始化
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//FactoryBean初始化
				if (isFactoryBean(beanName)) {
					//getBean通過有無前綴FACTORY_BEAN_PREFIX 識別是否FactoryBean 注2
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					//FactoryBean中bean默認是延遲創(chuàng)建的,如果FactoryBean實現(xiàn)了SmartFactoryBean,重載isEagerInit()返回true,則表示立即對FactoryBean中的bean進行創(chuàng)建 注3
					if (bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isEagerInit()) {
						//FactoryBean創(chuàng)建bean
						getBean(beanName);
					}
				}
				//普通bean初始化
				else {
					getBean(beanName);
				}
			}
		}

		//如果bean實現(xiàn)了SmartInitializingSingleton接口,則在初始化后回調(diào)afterSingletonsInstantiated
		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton smartSingleton) {
				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				smartSingleton.afterSingletonsInstantiated();
				smartInitialize.end();
			}
		}
	}

注1:bean定義相關見:
注2:getBean(beanName)在AbstractBeanFactory實現(xiàn),實際是調(diào)用AbstractBeanFactory.doGetBean(beanName, null, null, false),詳見:https://blog.csdn.net/davidwkx/article/details/130963899
注3:如果beanName是FactoryBean的名稱,getBean(“&”+beanName) 是獲取 FactoryBean 本身,而getBean(beanName) 獲取的是 FactoryBean 創(chuàng)建出來的 bean 實例。

resolveDependency / doResolveDependency

解析指定beanName對應的屬性,并將解析到的屬性名放入autowiredBeanNames,根據(jù)類型查找依賴關系文章來源地址http://www.zghlxwxcb.cn/news/detail-479367.html

	@Override
	@Nullable
	public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

		descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
		if (Optional.class == descriptor.getDependencyType()) {
			// Optional類型的注入處理
			return createOptionalDependency(descriptor, requestingBeanName);
		}
		else if (ObjectFactory.class == descriptor.getDependencyType() ||
				ObjectProvider.class == descriptor.getDependencyType()) {
			// ObjectFactory類型的注入處理
			return new DependencyObjectProvider(descriptor, requestingBeanName);
		}
		else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
			// Jsr330注解的注入處理
			return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
		}
		else {
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
					descriptor, requestingBeanName);
			if (result == null) {
				//非延遲加載的常規(guī)注入處理
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}

	@Nullable
	public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

		InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
		try {
			Object shortcut = descriptor.resolveShortcut(this);
			if (shortcut != null) {
				return shortcut;
			}

			// @Value注解的注入
			Class<?> type = descriptor.getDependencyType();
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
			if (value != null) {
				if (value instanceof String strValue) {
					// 占位符解析
					String resolvedValue = resolveEmbeddedValue(strValue);
					BeanDefinition bd = (beanName != null && containsBean(beanName) ?
							getMergedBeanDefinition(beanName) : null);
					// EL表達式
					value = evaluateBeanDefinitionString(resolvedValue, bd);
				}
				// 轉換類型
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				try {
					return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
				}
				catch (UnsupportedOperationException ex) {
					// A custom TypeConverter which does not support TypeDescriptor resolution...
					return (descriptor.getField() != null ?
							converter.convertIfNecessary(value, type, descriptor.getField()) :
							converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
				}
			}

			//解析多個bean,例如List、set、Map
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}

			// 依賴查詢
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (matchingBeans.isEmpty()) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}
			String autowiredBeanName;
			Object instanceCandidate;
			// 如果有多個匹配的Bean,就根據(jù)方法名稱進行匹配
			if (matchingBeans.size() > 1) {
				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
				if (autowiredBeanName == null) {
					if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
						return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
					}
					else {
						// In case of an optional Collection/Map, silently ignore a non-unique case:
						// possibly it was meant to be an empty collection of multiple regular beans
						// (before 4.3 in particular when we didn't even look for collection beans).
						return null;
					}
				}
				instanceCandidate = matchingBeans.get(autowiredBeanName);
			}
			else {
				// We have exactly one match.
				Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
				autowiredBeanName = entry.getKey();
				instanceCandidate = entry.getValue();
			}

			if (autowiredBeanNames != null) {
				autowiredBeanNames.add(autowiredBeanName);
			}
			if (instanceCandidate instanceof Class) {
				instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
			}
			Object result = instanceCandidate;
			if (result instanceof NullBean) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				result = null;
			}
			if (!ClassUtils.isAssignableValue(type, result)) {
				throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
			}
			return result;
		}
		finally {
			ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
		}
	}

到了這里,關于一起學SF框架系列5.4-模塊Beans-DefaultListableBeanFactory的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【藍牙系列】藍牙5.4到底更新了什么(2)

    【藍牙系列】藍牙5.4到底更新了什么(2)

    ??上一篇文章講了藍牙5.4的PAwR特征,非常適合應用在電子貨架標簽(ESL)領域, 但是實際應用場景中看,只有PAwR特性是不夠的,如何保證廣播數(shù)據(jù)的安全性,如何動態(tài)調(diào)節(jié)廣播的編碼方式以達到最優(yōu)的功耗。 這就需要用到本章需要介紹的藍牙5.4的幾個新特性。 下面再回

    2024年01月20日
    瀏覽(25)
  • 【藍牙系列】藍牙5.4到底更新了什么?(1)--- PAwR

    【藍牙系列】藍牙5.4到底更新了什么?(1)--- PAwR

    ??藍牙技術聯(lián)盟最近發(fā)布了藍牙5.4的核心規(guī)范,藍牙5.4規(guī)范的主要改進之一就是實現(xiàn)了單個接入點與數(shù)千個終端節(jié)點進行雙向無連接通信, 這一特性主要是針對電子貨架標簽(Electronic Shelf Label,ESL)市場。 ??電子貨架標簽是一種帶有信息收發(fā)功能的電子版的價簽顯示裝

    2024年02月08日
    瀏覽(26)
  • 一起學Elasticsearch系列-并發(fā)控制

    本文已收錄至Github,推薦閱讀 ?? Java隨想錄 微信公眾號:Java隨想錄 ES的并發(fā)控制是一種機制,用于處理多個同時對同一份數(shù)據(jù)進行讀寫操作的情況,以確保數(shù)據(jù)的一致性和正確性。 實現(xiàn)并發(fā)控制的方法主要有兩種:悲觀鎖和樂觀鎖。 悲觀鎖是一種并發(fā)控制機制,它基于一

    2024年04月27日
    瀏覽(23)
  • 一起學Elasticsearch系列-核心概念

    本文已收錄至Github,推薦閱讀 ?? Java隨想錄 微信公眾號:Java隨想錄 開個新的坑,創(chuàng)作關于Elasticsearch的系列文章 首先,讓我們簡單的了解一下Elasticsearch: Elasticsearch是一個開源的搜索和分析引擎,支持近實時的大數(shù)據(jù)存儲、搜索和分析。它基于Apache Lucene項目,提供全文搜索

    2024年02月01日
    瀏覽(51)
  • 一起學Elasticsearch系列-索引管理

    本文已收錄至Github,推薦閱讀 ?? Java隨想錄 微信公眾號:Java隨想錄 在Elasticsearch中,索引是對數(shù)據(jù)進行組織和存儲的基本單元。索引管理涉及創(chuàng)建、配置、更新和刪除索引,以及與索引相關的操作,如數(shù)據(jù)導入、搜索和聚合等。這些關鍵任務直接影響著系統(tǒng)性能、數(shù)據(jù)可用

    2024年02月02日
    瀏覽(23)
  • 一起學Elasticsearch系列-聚合查詢

    本文已收錄至Github,推薦閱讀 ?? Java隨想錄 微信公眾號:Java隨想錄 聚合查詢是 Elasticsearch 中一種強大的數(shù)據(jù)分析工具,用于從索引中提取和計算有關數(shù)據(jù)的統(tǒng)計信息。聚合查詢可以執(zhí)行各種聚合操作,如計數(shù)、求和、平均值、最小值、最大值、分組等,以便進行數(shù)據(jù)匯總和

    2024年01月22日
    瀏覽(20)
  • 一起學習ETCD系列——簡單安裝

    在微服務中服務發(fā)現(xiàn)是必不可少的,此時ETCD中間件就是一種可選項,其實ETCD除了服務發(fā)現(xiàn)功能,還有: 元數(shù)據(jù)存儲,比如存儲服務配置等數(shù)據(jù),以實現(xiàn)配置中心化,進行統(tǒng)一的,有版本記錄的變更管理; 分布式鎖; 選主,master-slave的軟件架構中可以通過etcd快速實現(xiàn)選主的

    2024年01月25日
    瀏覽(18)
  • 一起學Elasticsearch系列-模糊搜索

    本文已收錄至Github,推薦閱讀 ?? Java隨想錄 微信公眾號:Java隨想錄 在 Elasticsearch 中,模糊搜索是一種近似匹配的搜索方式。它允許找到與搜索詞項相似但不完全相等的文檔。 前綴匹配通過指定一個前綴值,搜索并匹配索引中指定字段的文檔,找出那些以該前綴開頭的結果

    2024年02月01日
    瀏覽(30)
  • 【一起擼個DL框架】3 前向傳播

    【一起擼個DL框架】3 前向傳播

    CSDN個人主頁:清風莫追 歡迎關注本專欄:《一起擼個DL框架》 GitHub獲取源碼:https://github.com/flying-forever/OurDL blibli視頻合集:https://space.bilibili.com/3493285974772098/channel/series 上一篇:【一起擼個DL框架】2 節(jié)點與計算圖的搭建 在上一節(jié)中,我們定義了加法節(jié)點和變量節(jié)點類,搭建

    2024年02月02日
    瀏覽(16)
  • 【一起擼個DL框架】4 反向傳播求梯度

    【一起擼個DL框架】4 反向傳播求梯度

    CSDN個人主頁:清風莫追 歡迎關注本專欄:《一起擼個DL框架》 GitHub獲取源碼:https://github.com/flying-forever/OurDL blibli視頻合集:https://space.bilibili.com/3493285974772098/channel/series 上一篇:【一起擼個DL框架】3 前向傳播 前面我們已經(jīng)介紹了前向傳播,而本節(jié)即將介紹的 反向傳播 中的

    2024年02月01日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包