最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Spring注入模型

 更新時(shí)間:2023年04月27日 09:23:17   作者:人生密密縫  
如果不深入到Spring的源碼,是很少有機(jī)會(huì)了解到Spring的注入模型(AutowireMode)。但是為了掃清我們學(xué)習(xí)Spring源碼的障礙,我們有必要了解下Spring的注入模型,感興趣的同學(xué)可以閱讀一下

Spring注入bean的方式

DI exists in two major variants: Constructor-based dependency injection and Setter-based dependency injection.

從Spring的官網(wǎng)中可以得知,Spring注入bean的方式由兩種,一種是通過構(gòu)造方法進(jìn)行注入,另外一種是通過setter方法進(jìn)行注入。
但熟悉Spring開發(fā)的同學(xué)在實(shí)際的開發(fā)中經(jīng)常使用的注入方式是通過@Autowired以及@Resource的方式來注入bean的。那么通過注解的方式注入是跟上面兩種注入方式是一樣的嗎?在研究這個(gè)問題之前,我們需要來了解Spring的注入模型。

Spring的注入模型

如果不深入到Spring的源碼,是很少有機(jī)會(huì)了解到Spring的注入模型(AutowireMode)。但是為了掃清我們學(xué)習(xí)Spring源碼的障礙,我們有必要了解下Spring的注入模型。
Spring的注入模型有四種,分別是:

  • autowire_no(0):默認(rèn)的注入模型,如果在beanA中注入beanB,如果沒有提供注解或者xml的注入方式,beanB是無法注入到beanA中的。
  • autowire_name(1):通過set方法注入,并且set的參數(shù)名必須和注入的bean名稱一樣,在xml中是通過byName
  • autowire_type(2):通過set方法注入,set的參數(shù)名可以隨意命名,但是類型必須和注入的bean的類型一樣,在xml中是通過byType的方式配置
  • autowire_constructor(3):通過構(gòu)造器注入

代碼示例

多說無益,我們直接上代碼來加深對(duì)這一概念的了解。

定義bean對(duì)象

我們簡(jiǎn)單定義兩個(gè)類,分別是Student和Address,并且將他們注入到Spring容器中。
Student.java如下

@Component
@Slf4j
public class Student {

    private Address address;

    public Student(){
        log.info("default constructor...");
    }

    public Student(Address address){
        log.info("constructor inject...{}", address);
        this.address = address;
    }

    public void setAddress(Address address){
        log.info("setter...{}", address);
        this.address = address;
    }

    public void showAddress(){
        this.address.info();
    }
}

Address.java如下

@Component
public class Address {

    public void info(){
        System.out.println("廣東省廣州市白云區(qū)");
    }
}

我們可以看到在Student中有一個(gè)屬性是Address,并且提供了默認(rèn)的構(gòu)造方法以及帶參數(shù)的構(gòu)造方法,同時(shí)還有一個(gè) set方法。

定義配置類

我們?cè)俣x一個(gè)config類,用來掃描這兩個(gè)類所在的包路徑,把這兩個(gè)類注入到Spring容器中。

@ComponentScan("org.example.autoModel.model")
public class MyBeanConfig {
}

定義后置處理器

在Spring中,我們可以在自己定義的后置處理器BeanFactoryPostProcessor,獲取到對(duì)應(yīng)的BeanDefinition。
相信大家在學(xué)習(xí)Spring的時(shí)候有了解過BeanDefinition,不熟悉的可以搜索下BeanDefinition的概念,如果閱讀過Spring的源碼的話,對(duì)BeanDefinition應(yīng)該就更加熟悉了。這里就不做過多的解釋了,后面在解讀Spring源碼的時(shí)候應(yīng)該也會(huì)涉及到這部分的知識(shí)。
簡(jiǎn)單的來說,就是一個(gè)對(duì)象被注入到Spring中,實(shí)際是被解析成BeanDefinition對(duì)象,里面保存了各種需要用到的信息,并且可以在后置處理器中獲取到對(duì)應(yīng)的BeanDefinition對(duì)象,然后對(duì)其做一些操作。

@Slf4j(topic = "e")
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition("student");
//        beanDefinition.setAutowireMode(3);
        log.debug("mode:{}",beanDefinition.getAutowireMode());
    }
}

上面代碼所示,我們可以獲取這個(gè)beanDefinition在Spring容器中對(duì)應(yīng)的autowireMode的值,并且可以修改這個(gè)autowireMode的值,來觀察下注入模型的改變,對(duì)bean的注入方式有什么影響。

定義測(cè)試方法

@Test
public void modelTest(){
   AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
   context.register(MyBeanConfig.class);
   context.register(MyBeanFactoryPostProcessor.class);
   context.refresh();
   Student student = context.getBean(Student.class);
   student.showAddress();
}

執(zhí)行測(cè)試方法,得出如下的結(jié)果。

如上面所示,我們可以得到對(duì)應(yīng)的autowireMode的值是0,并且是執(zhí)行了Student的默認(rèn)構(gòu)造方法,由于沒有將address屬性注入到student中,所在調(diào)用address對(duì)應(yīng)的方法的時(shí)候,拋出了空指針的異常。
針對(duì)上面的對(duì)象,我們可以簡(jiǎn)單分析下:

  • Spring默認(rèn)的注入模型是0
  • 注入模型是0,意味著執(zhí)行默認(rèn)的構(gòu)造方法,并且不會(huì)執(zhí)行set方法去進(jìn)行注入address這個(gè)對(duì)象,所以拋出了空指針異常

我們可以在后置處理器中,修改對(duì)應(yīng)autowioreMode的值,將autowireMode的值修改成1。

beanDefinition.setAutowireMode(1);

然后執(zhí)行該測(cè)試方法,得到下面的結(jié)果。

可以看到我們將注入模型的值修改成1,之后,spring就會(huì)通過set方法,將address注入到student中,就可以成功調(diào)用address的方法了。
當(dāng)然,我們將注入模型的值修改成2,也是注入成功的,并且也是通過set方法,只不過是byType和byName的區(qū)別。這個(gè)同學(xué)們可以自己嘗試下。
下面,我們將注入模型的值修改成3來看下執(zhí)行的結(jié)果。

beanDefinition.setAutowireMode(3);

結(jié)果如下:

可以看到,如果將注入模型的值修改成了3,那么Spring是通過帶參的構(gòu)造方法來注入給student的。
通過上面簡(jiǎn)單的例子,我們就可以了解到注入模型autowireMode對(duì)注入方式的影響,這為我們以后閱讀Spring的源碼打下了基礎(chǔ)。

自動(dòng)注入和手動(dòng)注入

上面我們將autowireMode值修改成1、2、3,就可以完成屬性的自動(dòng)注入。那如果我們不去修改autowireMode的值,而是使用注解來將屬性注入到student中,會(huì)是怎樣的結(jié)果呢?
我們來看下面的代碼:

@Component
@Slf4j
public class Student {

    @Autowired
    private Address address;

    public Student(){
        log.info("default constructor...");
    }

    public Student(Address address){
        log.info("constructor inject...{}", address);
        this.address = address;
    }

    public void setAddress(Address address){
        log.info("setter...{}", address);
        this.address = address;
    }

    public void showAddress(){
        this.address.info();
    }
}
@Slf4j(topic = "e")
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition("student");
//        beanDefinition.setAutowireMode(3);
        log.debug("mode:{}",beanDefinition.getAutowireMode());
    }
}

查看結(jié)果

我們發(fā)現(xiàn)使用@Autowired注解注入屬性的時(shí)候,注入模型的值是0,也就是默認(rèn)的值。
對(duì)于@Autowired的注解,我的看法是,使用注解注入屬性是手動(dòng)注入的方式,Spring提供自動(dòng)注入的方式只有set方法以及帶參的構(gòu)造方法。而注解的注入方式,只不過是xml手動(dòng)注入的一種簡(jiǎn)化,Spring內(nèi)部處理的機(jī)制都是類似的。
了解過xml配置的同學(xué)大概有些印象,我們需要指定bean中屬性所對(duì)應(yīng)的類的全路徑。而使用自動(dòng)注入,我們可以指定byType或者byName。由于xml方式太久沒用了,大概就是這么個(gè)意思吧。
所以我認(rèn)為@Autowired注入的方式,不是自動(dòng)注入,而是手動(dòng)注入,只不過Spring容器內(nèi)部幫我們處理了。當(dāng)然,關(guān)于Spring容器如何處理@Autowired注解的方式注入屬性的,同學(xué)們可以通過閱讀源碼來大致了解下。后面大概也會(huì)解讀下這部分的源碼。
以上便是鄙人對(duì)Spring注入模型的淺薄認(rèn)識(shí),如果有錯(cuò)誤的話,還請(qǐng)同學(xué)們多多包涵。

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

相關(guān)文章

  • SpringBoot中事務(wù)失效的原因詳解

    SpringBoot中事務(wù)失效的原因詳解

    這篇文章主要介紹了SpringBoot中事務(wù)失效的原因詳解,spring中的事務(wù)是依賴AOP的,AOP是通過動(dòng)態(tài)代理實(shí)現(xiàn)的,只有通過代理類訪問的方法才能被攔截,需要的朋友可以參考下
    2023-10-10
  • Java中如何自定義一個(gè)類加載器

    Java中如何自定義一個(gè)類加載器

    這篇文章主要介紹了Java中如何自定義一個(gè)類加載器,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • java:程序包javax.servlet.http不存在問題解決

    java:程序包javax.servlet.http不存在問題解決

    這篇文章主要給大家介紹了關(guān)于java:程序包javax.servlet.http不存在問題解決的相關(guān)資料,如果引用的包依賴的庫文件缺失或版本不匹配,就會(huì)導(dǎo)致"Java 程序包不存在"的錯(cuò)誤,需要的朋友可以參考下
    2023-10-10
  • 使用svn管理Maven項(xiàng)目的方法步驟

    使用svn管理Maven項(xiàng)目的方法步驟

    這篇文章主要介紹了使用svn管理Maven項(xiàng)目的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • SpringBoot內(nèi)置tomcat調(diào)優(yōu)測(cè)試優(yōu)化

    SpringBoot內(nèi)置tomcat調(diào)優(yōu)測(cè)試優(yōu)化

    這篇文章主要介紹了SpringBoot內(nèi)置tomcat調(diào)優(yōu)測(cè)試優(yōu)化,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • springboot的pom.xml配置方式

    springboot的pom.xml配置方式

    這篇文章主要介紹了springboot的pom.xml配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • spring boot自定義404錯(cuò)誤信息的方法示例

    spring boot自定義404錯(cuò)誤信息的方法示例

    這篇文章主要介紹了spring boot自定義404錯(cuò)誤信息的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • 解決IDEA使用maven創(chuàng)建Web項(xiàng)目,出現(xiàn)500錯(cuò)誤的問題

    解決IDEA使用maven創(chuàng)建Web項(xiàng)目,出現(xiàn)500錯(cuò)誤的問題

    本文主要介紹了在使用Maven創(chuàng)建項(xiàng)目并導(dǎo)入依賴寫完測(cè)試代碼后運(yùn)行出現(xiàn)500錯(cuò)誤的解決步驟,這種問題的根本原因是Tomcat啟動(dòng)后缺少某些支持的jar包,導(dǎo)致運(yùn)行出錯(cuò),解決方法是在項(xiàng)目結(jié)構(gòu)中找到Artifacts,點(diǎn)擊要編輯的項(xiàng)目
    2024-10-10
  • Java中使用print、printf、println的示例及區(qū)別

    Java中使用print、printf、println的示例及區(qū)別

    Java?的輸出方式一般有這三種,print、println、printf,它們都是?java.long?包里的System類中的方法,本文重點(diǎn)給大家介紹Java中使用print、printf、println的示例,需要的朋友可以參考下
    2023-05-05
  • SpringMVC用JsonSerialize日期轉(zhuǎn)換方法

    SpringMVC用JsonSerialize日期轉(zhuǎn)換方法

    下面小編就為大家?guī)硪黄猄pringMVC用JsonSerialize日期轉(zhuǎn)換方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起 小編過來看看吧
    2016-11-11

最新評(píng)論

武胜县| 济宁市| 收藏| 大化| 普安县| 武胜县| 磐石市| 林周县| 福清市| 辛集市| 军事| 松滋市| 防城港市| 洛南县| 阳朔县| 铁岭县| 汶上县| 柘城县| 宜兴市| 达拉特旗| 西畴县| 雷山县| 延津县| 西充县| 邵武市| 南和县| 淳化县| 霍邱县| 乌海市| 荣昌县| 东乌珠穆沁旗| 甘谷县| 泸水县| 安吉县| 永靖县| 桂东县| 鲜城| 临湘市| 成安县| 海口市| 陆川县|