色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

初學者必看的SpringBoo自動裝配原理2

jf_78858299 ? 來源:CSDN ? 作者:CC_且聽風吟 ? 2023-04-07 11:03 ? 次閱讀

4. BeanDefinition結構

既然講到了BeanDefinition,我們來看一下BeanDefinition里面究竟定義了些什么

讓我們點進AbstractBeanDefinition這個類,一探究竟

哇!好多成員變量,整個人都要看暈了@_@

我們來重點關注以下三個成員:

private volatile Object beanClass;
private int autowireMode = AUTOWIRE_NO;
private ConstructorArgumentValues constructorArgumentValues;

4.1 beanClass

這個屬性決定了該Bean定義的真正class到底是誰,接下來我們來做點實驗

我們定義兩個Bean類,A和B

@Component
public class A {
    @Value("我是AAA")
    private String name;
}
@Component
public class B {
    @Value("我是BBB")
    private String name;
}

接下來我們實現(xiàn)上面的BeanFactoryPostProcessor接口,來創(chuàng)建一個自定義的bean后置處理器

/**
 * 自定義的bean后置處理器
 * 通過這個MyBeanPostProcessor來修改bean定義的屬性
 * @author dzzhyk
 */
public class MyBeanPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        GenericBeanDefinition defA = (GenericBeanDefinition) beanFactory.getBeanDefinition("a");
        System.out.println("這里是MyBeanPostProcessor,我拿到了:" + defA.getBeanClassName());
    }
}

最后在XML配置文件中開啟包掃描

<context:component-scan base-package="pojo"/>
<context:annotation-config />

注意: 這里不要使用JavaConfig類來配置bean,不然會報如下錯誤

ConfigurationClassBeanDefinition cannot be cast to org.springframework.beans.factory.support.GenericBeanDefinition

這個錯誤出自這一句:

GenericBeanDefinition defA = (GenericBeanDefinition) beanFactory.getBeanDefinition("a");

最后,我們創(chuàng)建一個測試類:

public class Test {
    @org.junit.Test
    public void test(){
        ClassPathXmlApplicationContext ca = new ClassPathXmlApplicationContext("applicationContext.xml");
        A aaa = ca.getBean("a", A.class);
        System.out.println("最終拿到了==> " + aaa);
    }
}

測試運行!

這里是MyBeanPostProcessor,我拿到了:pojo.A
最終拿到了==> A(name=我是AAA, b=B(name=我是BBB))

可以看到MyBeanPostProcessor成功拿到了A的Bean定義,并且輸出了提示信息

接下來讓我們做點壞事

我們在MyBeanPostProcessor中修改A的Bean對象,將A的beanClass修改為B.class

System.out.println("這里是MyBeanPostProcessor,我修改了:"+ defA.getBeanClassName() + " 的class為 B.class");
// 把A的class改成B
defA.setBeanClass(B.class);

重新運行Test類,輸出了一些信息后:報錯了!

這里是MyBeanPostProcessor,我拿到了:pojo.A
這里是MyBeanPostProcessor,我修改了:pojo.A 的class為 B.class

BeanNotOfRequiredTypeException: 
 Bean named 'a' is expected to be of type 'pojo.A' but was actually of type 'pojo.B'

我要拿到一個A類對象,你怎么給我一個B類對象呢?這明顯不對

綜上所述,我們可以得出beanClass屬性控制bean定義的類

4.2 autowireMode

我們繼續(xù)看第二個屬性:autowireMode,自動裝配模式

我們在AbstractBeanDefinition源碼中可以看到:

private int autowireMode = AUTOWIRE_NO;

自動裝配模式默認是AUTOWIRE_NO,就是不開啟自動裝配

可選的常量值有以下四種:不自動裝配,通過名稱裝配,通過類型裝配,通過構造器裝配

  • AUTOWIRE_NO
  • AUTOWIRE_BY_NAME
  • AUTOWIRE_BY_TYPE
  • AUTOWIRE_CONSTRUCTOR

接下來我們來模擬一個自動裝配場景,仍然是A和B兩個類,現(xiàn)在在A類中添加B類對象

@Component
public class A {
    @Value("我是AAA")
    private String name;
    @Autowired
    private B b;
}

我們希望b對象能夠自動裝配,于是我們給他加上了@Autowired注解,其他的完全不變,我們自定義的MyBeanPostProcessor中也不做任何操作,讓我們運行測試類:

這里是MyBeanPostProcessor,我拿到了:pojo.A
最終拿到了==> A(name=我是AAA, b=B(name=我是BBB))

自動裝配成功了!我們拿到的A類對象里面成功注入了B類對象b

現(xiàn)在問題來了,如果我把@Autowired注解去掉,自動裝配會成功嗎?

這里是MyBeanPostProcessor,我拿到了:pojo.A
最終拿到了==> A(name=我是AAA, b=null)

必然是不成功的

但是我就是想要不加@Autowired注解,仍然可以實現(xiàn)自動裝配,需要怎么做?

這時就要在我們的MyBeanPostProcessor中做文章了,加入如下內容:

defA.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);

再輸出結果:

這里是MyBeanPostProcessor,我拿到了:pojo.A
最終拿到了==> A(name=我是AAA, b=B(name=我是BBB))

自動裝配成功了!這次我們可沒加@Autowired,在我們的自定義的bean后置處理器中設置了autowireMode屬性,也實現(xiàn)了自動裝配

綜上,autowireMode屬性是用來控制自動裝配模式的,默認值是AUTOWIRE_NO,即不自動裝配

4.3 constructorArgumentValues

constructorArgumentValues的字面含義是構造器參數(shù)

改變這個參數(shù)值,我們可以做到在實例化對象時指定特定的構造器

話不多說,show me your code:

因為要研究構造器,只能先”忍痛“關掉lombok插件,手寫一個pojo.Student類

/**
 * Student類
 * @author dzzhyk
 */
@Component
public class Student {
    private String name;
    private Integer age;

    public Student() {
        System.out.println("==>使用空參構造器 Student()");
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
        System.out.println("==>使用雙參數(shù)構造器 Student(String name, Integer age)");
    }
}

我們都知道,spring在實例化對象時使用的是對象的默認空參構造器:

我們新建一個測試方法test

@Test
public void test(){
    ApplicationContext ca = new ClassPathXmlApplicationContext("applicationContext.xml");
    Student student = ca.getBean("stu", Student.class);
    System.out.println("==>" + student);
}

運行可以得到下面結果:

這里是MyBeanPostProcessor,我拿到了:pojo.Student
==>使用空參構造器 Student()
==>pojo.Student@402e37bc

可以看到,確實使用了空參構造器

但是如何指定(自定義)使用哪個構造器呢?我根本看不見摸不著,Spring全幫我做了,實在是太貼心了。

接下來就聊聊constructorArgumentValues的使用:

我們在MyBeanPostProcessor中加入如下內容,對獲取到的pojo.Student的bean定義進行操作:

ConstructorArgumentValues args = new ConstructorArgumentValues();
args.addIndexedArgumentValue(0, "我指定的姓名");
args.addIndexedArgumentValue(1, 20);
defStu.setConstructorArgumentValues(args);

再次運行test:

這里是MyBeanPostProcessor,我拿到了:pojo.Student
==>使用雙參數(shù)構造器 Student(String name, Integer age)
==>pojo.Student@2f177a4b

可以看到這次使用了雙參數(shù)構造器

有人會好奇ConstructorArgumentValues到底是個什么東西,我點進源碼研究一番,結果發(fā)現(xiàn)這個類就是一個普通的包裝類,包裝的對象是ValueHolder,里面一個List一個Map

而ValueHolder這個對象繼承于BeanMetadataElement,就是構造器參數(shù)的一個包裝類型

通過這個例子我們可以看到ConstructorArgumentValues就是用來管控構造器參數(shù)的,指定這個值會在進行bean注入的時候選擇合適的構造器。

5. 裝配對象

現(xiàn)在我們把目光放回到SpringBoot的自動裝配上來,原來在真正進行bean實例化對象前,我們前面還有這些過程,尤其是存在使用后置處理器BeanFactoryPostProcessor來對bean定義進行各種自定義修改的操作。

經(jīng)過上面我們漫長的研究過程,我們終于可以回答第一個問題了:

自動裝配的對象:Bean定義 (BeanDefinition)

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • spring
    +關注

    關注

    0

    文章

    340

    瀏覽量

    14368
  • 源碼分析
    +關注

    關注

    0

    文章

    5

    瀏覽量

    5569
  • 自動裝配
    +關注

    關注

    0

    文章

    7

    瀏覽量

    668
收藏 人收藏

    評論

    相關推薦

    protel技術大全--初學者必看

    protel技術大全--初學者必看
    發(fā)表于 08-04 10:36

    PSOC1初學者必看的10個實例

    PSOC1初學者必看的10個實例
    發(fā)表于 11-19 16:33

    MATLAB入門教程-初學者必看

    MATLAB入門教程-初學者必看
    發(fā)表于 06-28 15:39

    Linux初學者必看!!!

    Linux初學者必看!!!
    發(fā)表于 01-07 21:35

    單片機入門秘籍,初學者必看

    初學者必看的單片機秘籍
    發(fā)表于 04-29 16:10

    PCB LAYOUT初學者必看

    PCBLAYOUT技術大全---初學者必看! PROTEL相關疑問 1.原理圖常見錯誤: (1)ERC報告管腳沒有接入信號: a.創(chuàng)建封裝時給管腳定義了I/O屬性; b.創(chuàng)建元件或放置元件時修改了不一致的grid屬性
    發(fā)表于 09-13 15:23 ?0次下載

    PSOC1初學者5個實驗,針對初學者的實驗

    PSOC1初學者5個實驗,針對初學者的實驗
    發(fā)表于 10-16 09:33 ?14次下載
    PSOC1<b class='flag-5'>初學者</b>5個實驗,針對<b class='flag-5'>初學者</b>的實驗

    初學者必看的基本電子技術概念

    初學者必看的基本電子技術概念
    發(fā)表于 05-17 11:41 ?0次下載

    初學者必看的電源測試項目要點及教程

    初學者必看的電源測試項目要點及教程
    發(fā)表于 07-01 14:09 ?31次下載

    初學者必看的LABVIEW工程師編程經(jīng)驗

    初學者必看的LABVIEW工程師編程經(jīng)驗
    發(fā)表于 07-12 14:24 ?29次下載

    ARM與嵌入式linux入門的建議(初學者必看)

    ARM與嵌入式linux入門的建議(初學者必看)(嵌入式開發(fā)培訓怎么樣)-該文檔為ARM與嵌入式linux入門的建議(初學者必看)總結文檔,是一份很不錯的參考資料,具有較高參考價值,感
    發(fā)表于 08-04 10:02 ?15次下載
    ARM與嵌入式linux入門的建議(<b class='flag-5'>初學者</b><b class='flag-5'>必看</b>)

    初學者必看的單片機程序匯總

    初學者必看的單片機程序匯總
    發(fā)表于 09-15 14:33 ?49次下載

    初學者必看SpringBoo自動裝配原理1

    學習SpringBoot,絕對避不開自動裝配這個概念,這也是SpringBoot的關鍵之一 本人也是SpringBoot的初學者,下面的一些總結都是結合個人理解和實踐得出的,如果有錯誤或者疏漏,請一定一定一定(不是歡迎,是
    的頭像 發(fā)表于 04-07 11:03 ?667次閱讀
    <b class='flag-5'>初學者</b><b class='flag-5'>必看</b>的<b class='flag-5'>SpringBoo</b><b class='flag-5'>自動</b><b class='flag-5'>裝配</b>原理1

    初學者必看SpringBoo自動裝配原理3

    學習SpringBoot,絕對避不開自動裝配這個概念,這也是SpringBoot的關鍵之一 本人也是SpringBoot的初學者,下面的一些總結都是結合個人理解和實踐得出的,如果有錯誤或者疏漏,請一定一定一定(不是歡迎,是
    的頭像 發(fā)表于 04-07 11:03 ?595次閱讀
    <b class='flag-5'>初學者</b><b class='flag-5'>必看</b>的<b class='flag-5'>SpringBoo</b><b class='flag-5'>自動</b><b class='flag-5'>裝配</b>原理3

    初學者必看SpringBoo自動裝配原理4

    學習SpringBoot,絕對避不開自動裝配這個概念,這也是SpringBoot的關鍵之一 本人也是SpringBoot的初學者,下面的一些總結都是結合個人理解和實踐得出的,如果有錯誤或者疏漏,請一定一定一定(不是歡迎,是
    的頭像 發(fā)表于 04-07 11:03 ?686次閱讀
    <b class='flag-5'>初學者</b><b class='flag-5'>必看</b>的<b class='flag-5'>SpringBoo</b><b class='flag-5'>自動</b><b class='flag-5'>裝配</b>原理4
    主站蜘蛛池模板: 忘忧草秋观看未满十八 | 1级午夜影院费免区 | 青青国产在线观看视频 | 日本一在线中文字幕 | 少妇伦子伦情品无吗 | jjzz动漫| 久久精品综合网中文字幕 | 美女穿丝袜被狂躁动态图 | 攻把受做哭边走边肉楼梯PLAY | 国产 欧美 亚洲 日韩视频 | 日本美女毛茸茸 | 黑丝女仆恋上我 | 国产亚洲精品AV片在线观看播放 | 国产精品你懂的在线播放 | 88蜜桃人妻无码精品系列 | 捏揉舔水插按摩师 | 浴室里强摁做开腿呻吟的漫画男男 | 亚洲人成网站在线播放 | 最近中文字幕在线中文视频 | 亚洲不卡高清免v无码屋 | 性虎成人网 | 青青在线视版在线播放 | 国产亚洲精品久久久久久久 | 在线免费观看视频a | 美女露出逼 | jiz在线播放jizijzz | 亚洲AV无码乱码国产精品品麻豆 | 久久无码av三级 | 在线视频免费国产成人 | 99热在线播放 | 最近免费中文字幕大全免费 | 达达兔欧美午夜国产亚洲 | 国产亚洲美女在线视频视频 | 91次元黄色观看 | 性生交片免费无码看人 | 一二三四在线观看韩国 | 国产AV精品久久久毛片 | 精品国产人成亚洲区 | 免费观看成人www精品视频在线 | 伦理片 a在线线版韩国 | 久艾草在线精品视频在线观看 |