欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解SpringBoot依賴注入和使用配置文件

 更新時(shí)間:2024年01月18日 15:28:27   作者:浩澤學(xué)編程  
這篇文章主要介紹了SpringBoot依賴注入和使用配置文件的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

前言

在上一篇文章中,講訴了SpringIoC的Bean裝配,但是對(duì)于如何進(jìn)行獲取,也就是Bean之間的依賴還未講訴,下面開(kāi)始講訴依賴注入(Dependency Injection,DI)以及如何使用屬性文件。涉及主要注解@Autowired、@Primary、@Quelifier、@PropertySource和@ConfigurationProperties。

一、??依賴注入

例:人類(Person)有時(shí)候利用一些動(dòng)物(Animal)去完成一些事情,比方說(shuō)狗(Dog)是用來(lái)看門的,貓(Cat)是用來(lái)抓老鼠的, 鸚鵡(Paηot)是用來(lái)迎客的……于是做一些事情就依賴于那些可愛(ài)的動(dòng)物。假設(shè)現(xiàn)在需要用狗狗來(lái)看門。

//定義人類接口
public interface Person {
    void service();
    void setAnimal(Animal animal);
}
//定義動(dòng)物接口
public interface Animal {
    void user();
}
//定義狗
@Component
public class Dog implements Animal {
    @Override
    public void user() {
        System.out.println("狗【" + Dog.class.getSimpleName() + "】是用來(lái)看門的");
    }
}
//定義年輕人
@Component
public class YoungPerson implements Person {
    @Autowired
    private Animal animal = null;
    @Override
    public void service() {
        this.animal.user();
    }
    @Override
    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}
//定義配置類
@Configuration
@ComponentScan("com.dragon.restart")//所有的包和類都在restart下
public class AppConfig {
}

測(cè)試類:

ApplicationContext ctx =new AnnotationConfigApplicationContext(AppConfig.class) ;
		Person person= ctx.getBean(YoungPerson.class) ;
		person.service() ;

在這里插入圖片描述

測(cè)試是成功的,這個(gè)時(shí)候SpringIoC 容器己經(jīng)通過(guò)注解@Autowired成功地將Dog注入到了 YoungPerson 實(shí)例中。 但是這只是一個(gè)比較簡(jiǎn)單的例子,我們有必要繼續(xù)探討@Autowired。

??注解@Autowired

@Autowired 是我們使用得最多的注解之一, 因此在這里需要進(jìn)一步地探討它。 它注入的機(jī)制最基本的一條是根據(jù)類型 (bytype), 我們回顧IoC 容器的頂級(jí)接口 BeanFactory,就可以知道 IoC 容器是通過(guò)getBean 方法獲取對(duì)應(yīng)Bean 的,而 getBean 又支持根據(jù)類型(by type)或者根據(jù)名稱(by name)。這里明顯根據(jù)類型注入,將狗狗實(shí)例注入Animal對(duì)象。
再回到上面的例子,我們只是創(chuàng)建了一個(gè)動(dòng)物一一狗,而實(shí)際上動(dòng)物還可以有貓 (Cat),貓可以為我們抓老鼠, 于是我們又創(chuàng)建了一個(gè)貓的類。

@Component
public class Cat implements Animal{
    @Override
    public void user() {
        System.out.println("貓【" + Cat.class.getSimpleName() + "】是抓老鼠的");
    }
}

好了,如果我們還使用著YoungPerson類,那么麻煩來(lái)了,因?yàn)檫@個(gè)類只是定義了一個(gè)動(dòng)物屬性(Animal),而我們卻有兩個(gè)動(dòng)物,一個(gè)狗, 一個(gè)貓, SpringIoC 如何注入呢?
運(yùn)行測(cè)試,可以看到IoC容器拋出異常,如下:

Description:
Field animal in com.dragon.restart.pojo.impl.YoungPerson required a single bean, but 2 were found:
    - cat: defined in file [E:\IDEA_projects\restart\target\classes\com\dragon\restart\pojo\Cat.class]
    - dog: defined in file [E:\IDEA_projects\restart\target\classes\com\dragon\restart\pojo\impl\Dog.class]

那么使用@Autowired 能處理這個(gè)問(wèn)題嗎?答案是肯定的。假設(shè)我們目前需要的是狗提供服務(wù),那么可以把屬性名稱轉(zhuǎn)化為dog,也就是原來(lái)YoungPerson的private Animal animal = null; 改為private An工mal dog = null;

@Component
public class YoungPerson implements Person {
    @Autowired
    private Animal dog = null;
    @Override
    public void service() {
        this.dog.user();
    }
    @Override
    public void setAnimal(Animal animal) {
        this.dog = animal;
    }
}

這里, 我們只是將屬性的名稱從animal 修改為了 dog,那么我們?cè)贉y(cè)試的時(shí)候,你可以看到是采用狗來(lái)提供服務(wù)的。那是因?yàn)椋繟utowired提供這樣的規(guī)則:首先它會(huì)根據(jù)類型找到對(duì)應(yīng)的Bean,如果對(duì)應(yīng)類型的 Bean 不是唯一的,那么它會(huì)根據(jù)其屬性名稱和 Bean 的名稱進(jìn)行匹配。如果匹配得上,就會(huì)使用該Bean:如果還無(wú)法匹配,就會(huì)拋出異常。這里還要注意的是@Autowired 是一個(gè)默認(rèn)必須找到對(duì)應(yīng) Bean 的注解,如果不能確定其標(biāo)注屬性一定會(huì)存在并且允許這個(gè)被標(biāo)注的屬性為null, 那么你可以配置@Autowired屬性 required 為 false@Autowired(required = false)

@Autowired除了可以標(biāo)注屬性外,還可以標(biāo)注方法, 如setAnimal方法,如下所示:

@Override
@Autowired 
public void setAnimal (Animal animal) { 
this.animal = animal;

這樣它也會(huì)使用setAnimal 方法從 IoC 容器中找到對(duì)應(yīng)的動(dòng)物進(jìn)行注入,甚至我們還可以使用在方法的參數(shù)上,后續(xù)文章會(huì)再談到它。

??消除歧義性——@Quelifier和@Primary

在上面我們發(fā)現(xiàn)有貓有狗的時(shí)候, 為了使@Autowired 能夠繼續(xù)使用,我們做了一個(gè)決定,將YoungPerson 的屬性名稱從 animal 修改為 dog。顯然這是一個(gè)憋屈的做法,好好的一個(gè)動(dòng)物,卻被我們定義為了狗,畢竟不能每次換個(gè)對(duì)象就改一次,這樣太麻煩了。產(chǎn)生注入失敗的問(wèn)題根本是按類型(bytype) 查找, 正如動(dòng)物可以有多種類型,這樣會(huì)造成 Spring IoC 容器注入的困擾,我們把這樣的一個(gè)問(wèn)題稱為歧義性。知道這個(gè)原因后, 那么這兩個(gè)注解是從哪個(gè)角度去解決這些問(wèn)題的呢?

首先是一個(gè)注解@Primary,它是一個(gè)修改優(yōu)先權(quán)的注解,當(dāng)我們有貓有狗的時(shí)候,假設(shè)這次需要使用貓, 那么只需要在貓類的定義上加入@Primarγ就可以了,如下:

@Component
@Primary
public class Dog implements Animal {
    @Override
    public void user() {
        System.out.println("狗【" + Dog.class.getSimpleName() + "】是用來(lái)看門的");
    }
}

這里的@Primary 的含義告訴 Spring IoC 容器, 當(dāng)發(fā)現(xiàn)有多個(gè)同樣類型的 Bean 時(shí),請(qǐng)優(yōu)先使用我進(jìn)行注入,于是再進(jìn)行測(cè)試時(shí)會(huì)發(fā)現(xiàn),系統(tǒng)將用狗狗為你提供服務(wù)。 因?yàn)楫?dāng) Spring 進(jìn)行注入的時(shí)候,雖然它發(fā)現(xiàn)存在多個(gè)動(dòng)物, 但因?yàn)镈og被標(biāo)注為了@Primarγ,所以優(yōu)先采用Dog的實(shí)例進(jìn)行了注入,這樣就通過(guò)優(yōu)先級(jí)的變換使得IoC容器知道注入哪個(gè)具體的實(shí)例來(lái)滿足依賴注入。然后,有時(shí)候@Primary 也可以使用在多個(gè)類上,也許無(wú)論是貓還是狗狗都可能帶上@Primary 注解, 其結(jié)果是IoC容器還是無(wú)法區(qū)分采用哪個(gè)Bean的實(shí)例進(jìn)行注入, 又或者說(shuō)我們需要更加靈活的機(jī)制來(lái)實(shí)現(xiàn)注入,那么**@Quelifier** 可以滿足你的這個(gè)愿望。

它將與@Autowired 組合在一起,通過(guò)類型和名稱一起找到Bean。我們知道Bean 名稱在 Spring IoC 容器中是唯一的標(biāo)識(shí),通過(guò)這個(gè)就可以消除歧義性了。此時(shí)你是否想起了BeanFactory接口中的這個(gè)方法呢?<T> T getBean(String name, Class<T> requiredType) throws BeansException;

代碼:

@Component
public class YoungPerson implements Person {
    @Autowired
    @Qualifier("dog")
    private Animal animal = null;
    @Override
    public void service() {
        this.animal.user();
    }
    @Override
    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}

一旦這樣聲明, Spring IoC 將會(huì)以類型和名稱去尋找對(duì)應(yīng)的Bean進(jìn)行注入。根據(jù)類型和名稱,顯然也只能找到狗狗為我們服務(wù)了。

??帶有參數(shù)的構(gòu)造方法類裝配

在上面,我們都基于一個(gè)默認(rèn)的情況,那就是不帶參數(shù)的構(gòu)造方法下實(shí)現(xiàn)依賴注入。但事實(shí)上,有些類只有帶有參數(shù)的構(gòu)造方法,于是上述的方法都不能再使用了。為了滿足這個(gè)功能,我們可以使用@Autowired 注解對(duì)構(gòu)造方法的參數(shù)進(jìn)行注入,例如,修改類YoungPerson來(lái)滿足這個(gè)功能。

database.driverName=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost:3306/my
database.username=root
database.password=root

@Autowired 和@Qualifier 注解,使其注入進(jìn)來(lái)。這里使用@Qualifier 是為了避免歧義性。當(dāng)然如果你的環(huán)境中不是有貓有狗,則可以完全不使用@Qualifier,而單單使用@Autowired就可以了。

二、??使用屬性文件

Java 開(kāi)發(fā)使用屬性文件已經(jīng)十分普遍,所以這里談?wù)勥@方面的內(nèi)容。在Spring Boot 中使用屬性文件,可以采用其默認(rèn)為我們準(zhǔn)備的application.properties,也可以使用自定義的配置文件。 應(yīng)該說(shuō)讀取配置文件的方法很多, 這里沒(méi)有必要面面俱到地介紹每一個(gè)細(xì)節(jié),只是介紹那些最常用的方法。

在SpringBoot項(xiàng)目的application.properties:

/**
 * @Version: 1.0.0
 * @Author: Dragon_王
 * @ClassName: DataBaseProperties
 * @Description: TODO描述
 * @Date: 2024/1/16 16:07
 */
@Component
public class DataBaseProperties {
    @Value("${database.driverName}")
    private String driverName = null;
    @Value("${database.url}")
    private String url = null;
    private String username = null;
    private String password = null;
    public void setDriverName(String driverName) {
        System.out.println(driverName);
        this.driverName = driverName;
    }
    public void setUrl(String url) {
        System.out.println(url);
        this.url = url;
    }
    @Value("${database.username}")
    public void setUsername(String username) {
        System.out.println(username);
        this.username = username;
    }
    @Value("${database.password}")
    public void setPassword(String password) {
        System.out.println(password);
        this.password = password;
    }
    public String getDriverName() {
        return driverName;
    }
    public String getUrl() {
        return url;
    }
    public String getUsername() {
        return username;
    }
    public String getPassword() {
        return password;
    }
}

創(chuàng)建個(gè)DataBaseProperties類:

/**
 * @Version: 1.0.0
 * @Author: Dragon_王
 * @ClassName: DataBaseProperties
 * @Description: TODO描述
 * @Date: 2024/1/16 16:07
 */
@Component
public class DataBaseProperties {
    @Value("${database.driverName}")
    private String driverName = null;
    @Value("${database.url}")
    private String url = null;
    private String username = null;
    private String password = null;
    public void setDriverName(String driverName) {
        System.out.println(driverName);
        this.driverName = driverName;
    }
    public void setUrl(String url) {
        System.out.println(url);
        this.url = url;
    }
    @Value("${database.username}")
    public void setUsername(String username) {
        System.out.println(username);
        this.username = username;
    }
    @Value("${database.password}")
    public void setPassword(String password) {
        System.out.println(password);
        this.password = password;
    }
    public String getDriverName() {
        return driverName;
    }
    public String getUrl() {
        return url;
    }
    public String getUsername() {
        return username;
    }
    public String getPassword() {
        return password;
    }
}

通過(guò)@Value注解, 使用${… }這樣的占位符讀取配置在屬性文件的內(nèi)容。這里的@Value 注解,既可以加載屬性, 也可以加在方法上。
這樣就能成功將屬性文件內(nèi)容成功注入了。但是我們可以使用過(guò)注解@ConfigurationProperties來(lái)簡(jiǎn)化一下,同樣能實(shí)現(xiàn)注入,如下:

/**
 * @Version: 1.0.0
 * @Author: Dragon_王
 * @ClassName: DataBaseProperties
 * @Description: TODO描述
 * @Date: 2024/1/16 16:07
 */
@Component
@ConfigurationProperties("database")
public class DataBaseProperties {
    private String driverName = null;
    private String url = null;
    private String username = null;
    private String password = null;
    public void setDriverName(String driverName) {
        System.out.println(driverName);
        this.driverName = driverName;
    }
    public void setUrl(String url) {
        System.out.println(url);
        this.url = url;
    }
    public void setUsername(String username) {
        System.out.println(username);
        this.username = username;
    }
    public void setPassword(String password) {
        System.out.println(password);
        this.password = password;
    }
    public String getDriverName() {
        return driverName;
    }
    public String getUrl() {
        return url;
    }
    public String getUsername() {
        return username;
    }
    public String getPassword() {
        return password;
    }
}

這里@ConfigurationProperties注解內(nèi)的database將會(huì)與屬性名組成屬性的全限定名去配置文件里查找,如屬性driveName就會(huì)和database組成database.driverName去查找,這里注意一下不需要管字母的大小寫,不影響。

如果我不用默認(rèn)的application.properties文件怎么辦呢?現(xiàn)在我們重新創(chuàng)建一個(gè)jdbc.properties文件,將原配置文件內(nèi)容移入其中。
DataBaseProperties 類不變?nèi)缟?,啟?dòng)類配置如下:

@SpringBootApplication
@PropertySource(value = {"classpath:jdbc.properties"},ignoreResourceNotFound = true)
public class RestartApplication {
	public static void main(String[] args) {
		SpringApplication.run(RestartApplication.class, args);
	}
}

在這里插入圖片描述

value 可以配置多個(gè)配置文件。使用 classpath 前綴, 意味著去類文件路徑下找到屬性文件;ignoreResourceNotFound 則是是否忽略配置文件找不到的問(wèn)題。 ignoreResourceNotFound 的默認(rèn)值為false,也就是沒(méi)有找到屬性文件, 就會(huì)報(bào)錯(cuò);這里配置為true,也就是找不到就忽略掉,不會(huì)報(bào)錯(cuò)。通過(guò)運(yùn)行日志,可以看出成功注入。

總結(jié)

以上就是依賴注入和使用配置配置文件的講解,歡迎大家一起討論。

到此這篇關(guān)于詳解SpringBoot依賴注入和使用配置文件的文章就介紹到這了,更多相關(guān)SpringBoot依賴注入和配置文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot jackson 精度處理問(wèn)題解決

    SpringBoot jackson 精度處理問(wèn)題解決

    由于JavaScript處理的最大數(shù)值限制,較大的雪花ID在JS中容易溢出,為解決此問(wèn)題,可在SpringMVC或SpringBoot中使用@RequestBody注解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • springboot2.0以上調(diào)度器配置線程池的實(shí)現(xiàn)

    springboot2.0以上調(diào)度器配置線程池的實(shí)現(xiàn)

    這篇文章主要介紹了springboot2.0以上調(diào)度器配置線程池的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • 解決Mybatis中foreach嵌套使用if標(biāo)簽對(duì)象取值的問(wèn)題

    解決Mybatis中foreach嵌套使用if標(biāo)簽對(duì)象取值的問(wèn)題

    這篇文章主要介紹了解決Mybatis中foreach嵌套使用if標(biāo)簽對(duì)象取值的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • SpringBoot自定義Starter及使用

    SpringBoot自定義Starter及使用

    這篇文章主要介紹了SpringBoot自定義Starter及使用,Starter是Spring Boot中的一個(gè)非常重要的概念,Starter相當(dāng)于模塊,它能將模塊所需的依賴整合起來(lái)并對(duì)模塊內(nèi)的Bean根據(jù)環(huán)境進(jìn)行自動(dòng)配置,需要的朋友可以參考下
    2023-07-07
  • SpringBoot?Security使用MySQL實(shí)現(xiàn)驗(yàn)證與權(quán)限管理

    SpringBoot?Security使用MySQL實(shí)現(xiàn)驗(yàn)證與權(quán)限管理

    安全管理是軟件系統(tǒng)必不可少的的功能。根據(jù)經(jīng)典的“墨菲定律”——凡是可能,總會(huì)發(fā)生。如果系統(tǒng)存在安全隱患,最終必然會(huì)出現(xiàn)問(wèn)題,這篇文章主要介紹了SpringBoot安全管理Spring?Security基本配置
    2022-11-11
  • Java?Validated?分組校驗(yàn)的使用

    Java?Validated?分組校驗(yàn)的使用

    這篇文章主要介紹了Java?Validated?分組校驗(yàn)的使用,文章記錄所以在這里記錄下分組校驗(yàn)注解@Validated的使用,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-02-02
  • 現(xiàn)代高效的java構(gòu)建工具gradle的快速入門

    現(xiàn)代高效的java構(gòu)建工具gradle的快速入門

    和Maven一樣,Gradle只是提供了構(gòu)建項(xiàng)目的一個(gè)框架,真正起作用的是Plugin,本文主要介紹了gradle入門,文中通過(guò)示例代碼介紹的非常詳細(xì),感興趣的小伙伴們可以參考一下
    2021-11-11
  • springboot多文件上傳實(shí)現(xiàn)使用postman測(cè)試多文件上傳接口

    springboot多文件上傳實(shí)現(xiàn)使用postman測(cè)試多文件上傳接口

    這篇文章主要介紹了springboot多文件上傳實(shí)現(xiàn)使用postman測(cè)試多文件上傳接口,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringBoot之spring.factories的使用方式

    SpringBoot之spring.factories的使用方式

    這篇文章主要介紹了SpringBoot之spring.factories的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • springboot 整合EhCache實(shí)現(xiàn)單服務(wù)緩存的操作方法

    springboot 整合EhCache實(shí)現(xiàn)單服務(wù)緩存的操作方法

    這篇文章主要介紹了springboot 整合EhCache實(shí)現(xiàn)單服務(wù)緩存的操作方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07

最新評(píng)論