欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

Spring中的BeanDefinition是什么

這篇文章主要講解了“Spring中的BeanDefinition是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Spring中的BeanDefinition是什么”吧!

創(chuàng)新互聯(lián)建站專注于企業(yè)全網(wǎng)整合營銷推廣、網(wǎng)站重做改版、滿洲網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5網(wǎng)站設(shè)計、成都做商城網(wǎng)站、集團公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為滿洲等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

1.BeanDefinition

在 Spring 容器中,我們廣泛使用的是一個一個的 Bean,BeanDefinition 從名字上就可以看出是關(guān)于 Bean 的定義。

事實上就是這樣,我們在 XML 文件中配置的 Bean 的各種屬性,這些屬性不僅僅是和對象相關(guān),Spring 容器還要解決 Bean 的生命周期、銷毀、初始化等等各種操作,我們定義的關(guān)于 Bean 的生命周期、銷毀、初始化等操作總得有一個對象來承載,那么這個對象就是 BeanDefinition。

XML 中定義的各種屬性都會先加載到 BeanDefinition 上,然后通過 BeanDefinition 來生成一個 Bean,從這個角度來說,BeanDefinition 和 Bean 的關(guān)系有點類似于類和對象的關(guān)系。

要理解 BeanDefinition,我們從 BeanDefinition 的繼承關(guān)系開始看起。

Spring中的BeanDefinition是什么  

BeanDefinition 是一個接口,繼承自 BeanMetadataElement 和 AttributeAccessor 接口。

  • BeanMetadataElement:該接口只有一個方法 getSource,該方法返回 Bean 的來源。
  • AttributeAccessor:該接口主要規(guī)范了問任意對象元數(shù)據(jù)的方法。

我們來看下 AttributeAccessor:

public interface AttributeAccessor {
 void setAttribute(String name, @Nullable Object value);
 @Nullable
 Object getAttribute(String name);
 @Nullable
 Object removeAttribute(String name);
 boolean hasAttribute(String name);
 String[] attributeNames();
}
 

這里定義了元數(shù)據(jù)的訪問接口,具體的實現(xiàn)則是 AttributeAccessorSupport,這些數(shù)據(jù)采用 LinkedHashMap 進行存儲。

這是 BeanDefinition 所繼承的兩個接口。接下來我們來看下 BeanDefinition 接口:

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
 String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
 String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
 int ROLE_APPLICATION = 0;
 int ROLE_SUPPORT = 1;
 int ROLE_INFRASTRUCTURE = 2;
 void setParentName(@Nullable String parentName);
 @Nullable
 String getParentName();
 void setBeanClassName(@Nullable String beanClassName);
 @Nullable
 String getBeanClassName();
 void setScope(@Nullable String scope);
 @Nullable
 String getScope();
 void setLazyInit(boolean lazyInit);
 boolean isLazyInit();
 void setDependsOn(@Nullable String... dependsOn);
 @Nullable
 String[] getDependsOn();
 void setAutowireCandidate(boolean autowireCandidate);
 boolean isAutowireCandidate();
 void setPrimary(boolean primary);
 boolean isPrimary();
 void setFactoryBeanName(@Nullable String factoryBeanName);
 @Nullable
 String getFactoryBeanName();
 void setFactoryMethodName(@Nullable String factoryMethodName);
 @Nullable
 String getFactoryMethodName();
 ConstructorArgumentValues getConstructorArgumentValues();
 default boolean hasConstructorArgumentValues() {
  return !getConstructorArgumentValues().isEmpty();
 }
 MutablePropertyValues getPropertyValues();
 default boolean hasPropertyValues() {
  return !getPropertyValues().isEmpty();
 }
 void setInitMethodName(@Nullable String initMethodName);
 @Nullable
 String getInitMethodName();
 void setDestroyMethodName(@Nullable String destroyMethodName);
 @Nullable
 String getDestroyMethodName();
 void setRole(int role);
 int getRole();
 void setDescription(@Nullable String description);
 @Nullable
 String getDescription();
 ResolvableType getResolvableType();
 boolean isSingleton();
 boolean isPrototype();
 boolean isAbstract();
 @Nullable
 String getResourceDescription();
 @Nullable
 BeanDefinition getOriginatingBeanDefinition();
}
 

BeanDefinition 中的方法雖然多,但是結(jié)合我們平時在 XML 中的配置,這些方法其實都很好理解:

  1. 首先一開始定義了兩個變量用來描述 Bean 是不是單例的,后面的 setScope/getScope 方法可以用來修改/獲取 scope 屬性。
  2. ROLE_xxx 用來描述一個 Bean 的角色,ROLE_APPLICATION 表示這個 Bean 是用戶自己定義的 Bean;ROLE_SUPPORT 表示這個 Bean 是某些復(fù)雜配置的支撐部分;ROLE_INFRASTRUCTURE 表示這是一個 Spring 內(nèi)部的 Bean,通過 setRole/getRole 可以修改。
  3. setParentName/getParentName 用來配置 parent 的名稱,這塊可能有的小伙伴使用較少,這個對應(yīng)著 XML 中的     <bean parent=""> 配置。
  4. setBeanClassName/getBeanClassName 這個就是配置 Bean 的 Class 全路徑,對應(yīng) XML 中的     <bean class=""> 配置。
  5. setLazyInit/isLazyInit 配置/獲取 Bean 是否懶加載,這個對應(yīng)了 XML 中的     <bean lazy-init=""> 配置。
  6. setDependsOn/getDependsOn 配置/獲取 Bean 的依賴對象,這個對應(yīng)了 XML 中的     <bean depends-on=""> 配置。
  7. setAutowireCandidate/isAutowireCandidate 配置/獲取 Bean 是否是自動裝配,對應(yīng)了 XML 中的     <bean autowire-candidate=""> 配置。
  8. setPrimary/isPrimary 配置/獲取當(dāng)前 Bean 是否為首選的 Bean,對應(yīng)了 XML 中的     <bean primary=""> 配置。
  9. setFactoryBeanName/getFactoryBeanName 配置/獲取 FactoryBean 的名字,對應(yīng)了 XML 中的     <bean factory-bean=""> 配置。
  10. setFactoryMethodName/getFactoryMethodName 和上一條成對出現(xiàn)的,對應(yīng)了 XML 中的     <bean factory-method=""> 配置,不再贅述。
  11. getConstructorArgumentValues 返回該 Bean 構(gòu)造方法的參數(shù)值。
  12. hasConstructorArgumentValues 判斷上一條是否是空對象。
  13. getPropertyValues 這個是獲取普通屬性的集合。
  14. hasPropertyValues 判斷上一條是否為空對象。
  15. setInitMethodName/setDestroyMethodName 配置 Bean 的初始化方法、銷毀方法。
  16. setDescription/getDescription 配置/返回 Bean 的描述。
  17. isSingleton Bean 是否為單例。
  18. isPrototype Bean 是否為原型。
  19. isAbstract Bean 是否抽象。
  20. getResourceDescription 返回定義 Bean 的資源描述。
  21. getOriginatingBeanDefinition 如果當(dāng)前 BeanDefinition 是一個代理對象,那么該方法可以用來返回原始的 BeanDefinition 。

這個就是 BeanDefinition 的定義以及它里邊方法的含義。

 

2.BeanDefinition 實現(xiàn)類

上面只是 BeanDefinition 接口的定義,BeanDefinition 還擁有諸多實現(xiàn)類,我們也來大致了解下。

先來看一張繼承關(guān)系圖:

Spring中的BeanDefinition是什么  

這么多實現(xiàn)類看著有點眼花繚亂,不過搞清楚了每一個接口和類的作用,再看就很容易了。

 

2.1 AbstractBeanDefinition

AbstractBeanDefinition 是一個抽象類,它根據(jù) BeanDefinition 中定義的接口提供了相應(yīng)的屬性,并實現(xiàn)了 BeanDefinition 中定義的一部分方法。BeanDefinition 中原本只是定義了一系列的 get/set 方法,并沒有提供對應(yīng)的屬性,在 AbstractBeanDefinition 中將所有的屬性定義出來了。

后面其他的實現(xiàn)類也基本上都是在 AbstractBeanDefinition 的基礎(chǔ)上完成的。

 

2.2 RootBeanDefinition

這是一個比較常用的實現(xiàn)類,對應(yīng)了一般的元素標(biāo)簽。

 

2.3 ChildBeanDefinition

可以讓子 BeanDefinition 定義擁有從父 BeanDefinition 那里繼承配置的能力。

 

2.4 GenericBeanDefinition

GenericBeanDefinition 是從 Spring2.5 以后新加入的 BeanDefinition 實現(xiàn)類。GenericBeanDefinition 可以動態(tài)設(shè)置父 Bean,同時兼具 RootBeanDefinition 和 ChildBeanDefinition 的功能。

 

2.5 AnnotatedBeanDefinition

表示注解類型 BeanDefinition,擁有獲取注解元數(shù)據(jù)和方法元數(shù)據(jù)的能力。

 

2.6 AnnotatedGenericBeanDefinition

使用了 @Configuration 注解標(biāo)記配置類會解析為 AnnotatedGenericBeanDefinition。

 

3.實踐

理論講了這么多,接下來我們通過幾行代碼來實踐下,驗證一下我們前面所說的對不對。

首先項目中添加 spring-context 依賴,如下:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.6.RELEASE</version>
</dependency>
 

然后我們來創(chuàng)建一個 User 類,如下:

public class User {
    private String username;
    private String address;

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", address='" + address + '\'' +
                '}';
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}
 

接下來我們先來驗證 RootBeanDefinition。我們自己純手工定義一個 RootBeanDefinition,并且將之注冊到 Spring 容器中去。

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("username", "javaboy");
pvs.add("address", "www.javaboy.org");
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(User.class, null, pvs);
ctx.registerBeanDefinition("user",rootBeanDefinition);
ctx.refresh();
User bean = ctx.getBean(User.class);
System.out.println(bean);
 

MutablePropertyValues 是定義對象中的一個一個屬性,構(gòu)造 RootBeanDefinition 的時候,我們傳入了類名稱和屬性集合,最終把 rootBeanDefinition 注冊到容器中去。剩下的事情由容器完成,然后我們就可以從容器中獲取到 User 對象了。

最終輸出結(jié)果如下:

User{username='javaboy', address='www.javaboy.org'}
 

看了這個例子,小伙伴們應(yīng)該能夠大致明白,我們在 XML 中定義的各種屬性,就是先被解析到 BeanDefinition 中,然后再注冊到 Spring 容器中去,最后拿到我們需要的 Bean。

ChildBeanDefinition 具有從父 Bean 繼承數(shù)據(jù)的能力,我們來看下這個怎么用。

首先新建一個 Person 類,Person 類在 User 類的基礎(chǔ)上增加一個 nickname 屬性,這樣 Person 就可以繼承到 User 的 username 和 address 兩個屬性的值了:

public class Person {
    private String username;
    private String address;
    private String nickname;

    @Override
    public String toString() {
        return "Person{" +
                "username='" + username + '\'' +
                ", address='" + address + '\'' +
                ", nickname='" + nickname + '\'' +
                '}';
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
}
 

接下來自定義 ChildBeanDefinition:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("username", "javaboy");
pvs.add("address", "www.javaboy.org");
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(User.class, null, pvs);
ctx.registerBeanDefinition("user",rootBeanDefinition);
ChildBeanDefinition childBeanDefinition = new ChildBeanDefinition("user");
childBeanDefinition.setBeanClass(Person.class);
childBeanDefinition.getPropertyValues().add("nickname", "江南一點雨");
ctx.registerBeanDefinition("person", childBeanDefinition);
ctx.refresh();
User user = ctx.getBean(User.class);
Person person = ctx.getBean(Person.class);
System.out.println("user = " + user);
System.out.println("person = " + person);
 

首先定義 RootBeanDefinition 并注冊到 Spring 容器中,然后再定義 ChildBeanDefinition,ChildBeanDefinition 繼承了 RootBeanDefinition 中現(xiàn)有的屬性值。

最后我們從 Spring 容器中獲取 User 和 Person,打印結(jié)果如下:

user = User{username='javaboy', address='www.javaboy.org'}
person = Person{username='javaboy', address='www.javaboy.org', nickname='江南一點雨'}
 

可以看到,Person 確實繼承了 User 的屬性值。

RootBeanDefinition 和 ChildBeanDefinition 都可以被 GenericBeanDefinition 代替,效果一樣,如下:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("username", "javaboy");
pvs.add("address", "www.javaboy.org");
GenericBeanDefinition rootBeanDefinition = new GenericBeanDefinition();
rootBeanDefinition.setBeanClass(User.class);
rootBeanDefinition.setPropertyValues(pvs);
ctx.registerBeanDefinition("user",rootBeanDefinition);
GenericBeanDefinition childBeanDefinition = new GenericBeanDefinition();
childBeanDefinition.setParentName("user");
childBeanDefinition.setBeanClass(Person.class);
childBeanDefinition.getPropertyValues().add("nickname", "江南一點雨");
ctx.registerBeanDefinition("person", childBeanDefinition);
ctx.refresh();
User user = ctx.getBean(User.class);
Person person = ctx.getBean(Person.class);
System.out.println("user = " + user);
System.out.println("person = " + person);
 

運行結(jié)果如下:

user = User{username='javaboy', address='www.javaboy.org'}
person = Person{username='javaboy', address='www.javaboy.org', nickname='江南一點雨'}
 

可以看到,和前面的運行效果一致。

在我們本系列前面文章(Spring 源碼第一篇開整!配置文件是怎么加載的?)的案例中,默認(rèn)使用的也是 GenericBeanDefinition,如下:

Spring中的BeanDefinition是什么  

現(xiàn)在 Spring Boot 廣泛流行之后,Java 配置使用越來越多,以 @Configuration 注解標(biāo)記配置類會被解析為 AnnotatedGenericBeanDefinition;以 @Bean 注解標(biāo)記的 Bean 會被解析為 ConfigurationClassBeanDefinition。

我們新建一個 MyConfig 配置類,如下:

@Configuration
public class MyConfig {
    @Bean
    User user() {
        return new User();
    }
}
 

查看獲取到的 BeanDefinition 結(jié)果如下:

Spring中的BeanDefinition是什么  

而其他 @Service、@Controller、@Repository 以及 @Component 等注解標(biāo)記的 Bean 則會被識別為 ScannedGenericBeanDefinition。

感謝各位的閱讀,以上就是“Spring中的BeanDefinition是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Spring中的BeanDefinition是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

名稱欄目:Spring中的BeanDefinition是什么
本文URL:http://chinadenli.net/article40/joijeo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、品牌網(wǎng)站制作、品牌網(wǎng)站建設(shè)微信公眾號、定制開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)
一区二区三区在线不卡免费| 日韩中文字幕欧美亚洲| 亚洲天堂精品在线视频| 麻豆最新出品国产精品| 日韩国产传媒在线精品| 国产精品久久精品国产| 手机在线观看亚洲中文字幕| 欧美日韩最近中国黄片| 欧美日韩综合综合久久久| 91久久精品国产一区蜜臀| 少妇视频一区二区三区| 日本丁香婷婷欧美激情| 成人国产激情在线视频| 久久国内午夜福利直播| 婷婷亚洲综合五月天麻豆 | 最新午夜福利视频偷拍| 国产一区二区精品高清免费| 欧美日韩精品视频在线| 在线欧洲免费无线码二区免费| 日韩成人动画在线观看| 91超频在线视频中文字幕| 亚洲一区二区三在线播放| 日韩一区二区三区在线欧洲| 久久国产精品亚州精品毛片| 亚洲熟女国产熟女二区三区| 日本人妻丰满熟妇久久| 精品欧美在线观看国产| 麻豆亚州无矿码专区视频| 亚洲男人天堂成人在线视频| 日本午夜免费啪视频在线 | 少妇成人精品一区二区| 久久久精品区二区三区| 护士又紧又深又湿又爽的视频| 东京热男人的天堂一二三区| 国产日韩欧美综合视频| 国产午夜精品美女露脸视频| 日本大学生精油按摩在线观看| 五月天综合网五月天综合网| 日本人妻中出在线观看| 中文字幕一区二区熟女| 91精品欧美综合在ⅹ|