摘要:但是這些對(duì)象在容器中,到底是以什么形式存在,具有哪些屬性行為呢今天我們進(jìn)入到源碼來(lái)一探究竟。只對(duì)注解有效,配置文件中可以通過顯示注入配置為主要候選。至于各屬性的詳細(xì)使用和注意事項(xiàng),后續(xù)會(huì)有多帶帶的文章來(lái)解析,盡情期待
Spring版本為5.1.5簡(jiǎn)述
用過spring的人都知道,我們將對(duì)象注入到spring容器中,交給spring來(lái)幫我們管理。這種對(duì)象我們稱之為bean對(duì)象。但是這些bean對(duì)象在spring容器中,到底是以什么形式存在,具有哪些屬性、行為呢?今天我們進(jìn)入到spring源碼來(lái)一探究竟。
bean的創(chuàng)建工廠BeanFactory有個(gè)默認(rèn)實(shí)現(xiàn)類DefaultListableBeanFactory,內(nèi)部有個(gè)存放所有注入bean對(duì)象信息的Map
/** Map of bean definition objects, keyed by bean name. */ private final MapbeanDefinitionMap = new ConcurrentHashMap<>(256);
Map的value對(duì)象BeanDefinition就是spring中對(duì)bean的定義和描述,具體概述如下:
屬性 | 行為 | 解釋 |
---|---|---|
parentName | String getParentName(); void setParentName(@Nullable String parentName); |
bean定義對(duì)象的父類定義對(duì)象名稱 |
beanClassName | String getBeanClassName(); void setBeanClassName(@Nullable String beanClassName); |
bean對(duì)象的實(shí)際class類 |
scope | String getScope(); void setScope(@Nullable String scope); |
bean對(duì)象是否為單例 |
lazyInit | boolean isLazyInit(); void setLazyInit(boolean lazyInit); |
是否懶加載 |
dependsOn | String[] getDependsOn(); void setDependsOn(@Nullable String... dependsOn); |
設(shè)置依賴的bean對(duì)象,被依賴的bean對(duì)象總是會(huì)比當(dāng)前bean對(duì)象先創(chuàng)建 |
autowireCandidate | boolean isAutowireCandidate(); void setAutowireCandidate(boolean autowireCandidate); |
設(shè)置是否可以自動(dòng)注入。只對(duì)@Autowired注解有效,配置文件中可以通過property顯示注入 |
primary | boolean isPrimary(); void setPrimary(boolean primary); |
配置bean為主要候選bean。當(dāng)同一個(gè)接口的多個(gè)實(shí)現(xiàn)類或者一個(gè)類多次注入到spring容器時(shí),通過該屬性來(lái)配置某個(gè)bean為主候選bean,通過類型來(lái)注入時(shí),默認(rèn)為使用主候選bean注入 |
factoryBeanName | String getFactoryBeanName(); void setFactoryBeanName(@Nullable String factoryBeanName); |
設(shè)置創(chuàng)建bean的工廠名稱 |
factoryMethodName | String getFactoryMethodName(); void setFactoryMethodName(@Nullable String factoryMethodName); |
設(shè)置創(chuàng)建bean的工廠中,創(chuàng)建bean的具體方法 |
initMethodName | String getInitMethodName(); void setInitMethodName(@Nullable String initMethodName); |
設(shè)置創(chuàng)建bean時(shí),默認(rèn)初始化的方法 |
destroyMethodName | String getDestroyMethodName(); void setDestroyMethodName(@Nullable String destroyMethodName); |
設(shè)置銷毀bean時(shí)調(diào)用的方法名稱。注意需要調(diào)用context的close()方法才會(huì)調(diào)用 |
role | int getRole(); void setRole(int role); |
設(shè)置bean的分類。 APPLICATION:用戶 INFRASTRUCTURE:完全內(nèi)部使用,與用戶無(wú)關(guān) SUPPORT:某些復(fù)雜配置的一部分 |
description | String getDescription(); void setDescription(@Nullable String description); |
對(duì)bean對(duì)象的描述 |
ConstructorArgumentValues | getConstructorArgumentValues(); | 記錄構(gòu)造函數(shù)注入屬性,通過bean的水性constructor-arg來(lái)注入 |
MutablePropertyValues | getPropertyValues(); | 普通屬性集合 |
注意:BeanDefinition是一個(gè)接口,內(nèi)部只定義了bean對(duì)象的一些基本行為。上表中的屬性在BeanDefinition中并不是真實(shí)存在的,只是通過set、get方法來(lái)設(shè)置和獲取。以下抽取出部分BeanDefinition源代碼供大家感知下
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { /** * Override the target scope of this bean, specifying a new scope name. * @see #SCOPE_SINGLETON * @see #SCOPE_PROTOTYPE */ void setScope(@Nullable String scope); /** * Return the name of the current target scope for this bean, * or {@code null} if not known yet. */ @Nullable String getScope(); }實(shí)際使用
假設(shè)有以下兩個(gè)bean,Java代碼如下
MyTestBean
package com.yuanweiquan.learn.bean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Description; public class MyTestBean { @Autowired private AutowireCandidateBean autowireCandidateBean; public void init() { System.out.println("inti MyTestBean"); } public AutowireCandidateBean getAutowireCandidateBean() { return autowireCandidateBean; } public void setAutowireCandidateBean(AutowireCandidateBean bean) { this.autowireCandidateBean = bean; } }
AutowireCandidateBean
package com.yuanweiquan.learn.bean; public class AutowireCandidateBean { public void initBean() { System.out.println("init AutowireCandidateBean"); } public void destroyBean() { System.out.println("destroy AutowireCandidateBean"); } }
下面看如何在配置文件applicationContext.xml來(lái)進(jìn)行配置
autowireCandidateBean description
接下來(lái)就是測(cè)試代碼
FileSystemXmlApplicationContext factory = new FileSystemXmlApplicationContext("classpath:applicationContext.xml"); BeanDefinition myTestBeanDefinition = factory.getBeanFactory().getBeanDefinition("autowireCandidateBean"); //輸出 System.out.println("bean description:" + myTestBeanDefinition.getDescription()); System.out.println("bean class name:" + myTestBeanDefinition.getBeanClassName()); System.out.println("parent name:" + myTestBeanDefinition.getParentName()); System.out.println("scope:" + myTestBeanDefinition.getScope()); System.out.println("is lazyinit:" + myTestBeanDefinition.isLazyInit()); System.out.println("depends On:" + myTestBeanDefinition.getDependsOn()); System.out.println("is autowireCandidate:" + myTestBeanDefinition.isAutowireCandidate()); System.out.println("is primary:" + myTestBeanDefinition.isPrimary()); System.out.println("factory bean name:"+myTestBeanDefinition.getFactoryBeanName()); System.out.println("factory bean method name:" + myTestBeanDefinition.getFactoryMethodName()); System.out.println("init method name:" + myTestBeanDefinition.getInitMethodName()); System.out.println("destory method name:" + myTestBeanDefinition.getDestroyMethodName()); System.out.println("role:" + myTestBeanDefinition.getRole()); //關(guān)閉context,否則不會(huì)調(diào)用bean的銷毀方法 factory.close();
控制臺(tái)輸出如下
init AutowireCandidateBean inti MyTestBean bean description:autowireCandidateBean description bean class name:com.yuanweiquan.learn.bean.AutowireCandidateBean parent name:myTestBean scope:singleton is lazyinit:false depends On:null is autowireCandidate:true is primary:true factory bean name:null factory bean method name:null init method name:initBean destory method name:destroyBean role:0 destroy AutowireCandidateBean
到此為止,通過上面的信息,我們能清晰的看到各屬性對(duì)應(yīng)的值。上述測(cè)試代碼的目的是讓我們大家能看到bean在spring容器中,以什么樣子的形式存在,具體有哪些屬性,屬性的值以及默認(rèn)值是多少。也算初步的揭開了spring容器中bean的面紗,其實(shí)并沒有我們想象中的那么神秘。至于各屬性的詳細(xì)使用和注意事項(xiàng),后續(xù)會(huì)有多帶帶的文章來(lái)解析,盡情期待!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/73856.html
摘要:前言以下源碼基于版本解析。實(shí)現(xiàn)源碼分析對(duì)于的實(shí)現(xiàn),總結(jié)來(lái)說(shuō)就是定位加載和注冊(cè)。定位就是需要定位配置文件的位置,加載就是將配置文件加載進(jìn)內(nèi)存注冊(cè)就是通過解析配置文件注冊(cè)。下面我們從其中的一種使用的方式一步一步的分析的實(shí)現(xiàn)源碼。 前言 以下源碼基于Spring 5.0.2版本解析。 什么是IOC容器? 容器,顧名思義可以用來(lái)容納一切事物。我們平常所說(shuō)的Spring IOC容器就是一個(gè)可以容...
摘要:在介紹自定義標(biāo)簽解析前,先放一張圖幫助大家理解以下是如何從文件中解析并加載的。自定義標(biāo)簽比如的值為根據(jù)獲取到的,獲取對(duì)應(yīng)的對(duì)象。關(guān)于和加載先后順序的問題最后再集合一個(gè)小例子總結(jié)下吧當(dāng)我們先解析了元素時(shí),我們會(huì)遍歷所有已經(jīng)注冊(cè)注冊(cè)表中。 今天我們來(lái)談?wù)?Dubbo XML 配置相關(guān)內(nèi)容。關(guān)于這部分內(nèi)容我打算分為以下幾個(gè)部分進(jìn)行介紹: Dubbo XML Spring 自定義 XML 標(biāo)...
摘要:簡(jiǎn)介為了寫容器源碼分析系列的文章,我特地寫了一篇容器的導(dǎo)讀文章。在做完必要的準(zhǔn)備工作后,從本文開始,正式開始進(jìn)入源碼分析的階段。從緩存中獲取單例。返回以上就是和兩個(gè)方法的分析。 1. 簡(jiǎn)介 為了寫 Spring IOC 容器源碼分析系列的文章,我特地寫了一篇 Spring IOC 容器的導(dǎo)讀文章。在導(dǎo)讀一文中,我介紹了 Spring 的一些特性以及閱讀 Spring 源碼的一些建議。在...
摘要:本文是針對(duì)的來(lái)進(jìn)行解析并將解析后的信息使用作為載體進(jìn)行注冊(cè)已經(jīng)在中被標(biāo)記為不建議使用,但是我們分析源碼不影響,因?yàn)樵创a并未改變,并依舊使用和進(jìn)行的解析和注冊(cè)工作,本篇博客是跟源碼一步步看怎么實(shí)現(xiàn)的注冊(cè),源碼為源碼已經(jīng)在每一行上加了注釋,方便 本文是針對(duì)Srping的XMLBeanFactory來(lái)進(jìn)行解析xml并將解析后的信息使用GenericBeanDefinition作為載體進(jìn)行注冊(cè)...
摘要:進(jìn)一步解析其他所有屬性并統(tǒng)一封裝至類型的實(shí)例中。是一個(gè)接口,在中存在三種實(shí)現(xiàn)以及。通過將配置文件中配置信息轉(zhuǎn)換為容器的內(nèi)部表示,并將這些注冊(cè)到中。容器的就像是配置信息的內(nèi)存數(shù)據(jù)庫(kù),主要是以的形式保存。而代碼的作用就是實(shí)現(xiàn)此功能。 前言:繼續(xù)前一章。 一、porfile 屬性的使用 如果你使用過SpringBoot, 你一定會(huì)知道porfile配置所帶來(lái)的方便, 通過配置開發(fā)環(huán)境還是生產(chǎn)...
閱讀 1484·2021-11-22 09:34
閱讀 2663·2021-11-12 10:36
閱讀 1182·2021-11-11 16:55
閱讀 2396·2020-06-22 14:43
閱讀 1523·2019-08-30 15:55
閱讀 2038·2019-08-30 15:53
閱讀 1826·2019-08-30 10:50
閱讀 1275·2019-08-29 12:15