Spring 注入 Bean 的 7 種方式,還有誰不會??


來源:juejin.cn/post/6844903813753602056

通過注解注入Bean

背景

我們談到Spring的時候一定會提到IOC容器、DI依賴注入,Spring通過將一個個類標注為Bean的方法注入到IOC容器中,達到了控制反轉的效果。那么我們剛開始接觸Bean的時候,一定是使用xml文件,一個一個的注入,就例如下面這樣。

 <bean id="bean" class="beandemo.Bean" />

我們的項目一般很大的話,就需要成千上百個Bean去使用,這樣寫起來就很繁瑣。那么Spring就幫我們實現了一種通過注解來實現注入的方法。只需要在你需要注入的類前面加上相應的注解,Spring就會幫助我們掃描到他們去實現注入。

xml掃描包的方式

 <context:component-scan base-package="com.company.beandemo"/>

通過注解注入的一般形式

一般情況下,注入Bean有一個最直白,最易懂的方式去實現注入,下面廢話先不多說,先貼代碼。

Bean類

public class MyBean{
}

Configuration類

//創建一個class配置文件
@Configuration
public class MyConfiguration{
 //將一個Bean交由Spring進行管理
    @Bean
    public MyBean myBean(){
        return new MyBean();
    }
}

Test類

與xml有一點不同,這里在Test中,實例化的不再是ClassPathXmlApplicationContext,而是獲取的AnnotationConfigApplicationContext實例。

ApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
MyBean myBean = cotext.getBean("myBean",MyBean.class);
System.out.println("myBean = " + myBean);

上面的代碼中MyBean也就是我們需要Spring去管理的一個Bean,他只是一個簡單的類。而MyConfiguration中,我們首先用@Configuration注解去標記了該類,這樣標明該類是一個Spring的一個配置類,在加載配置的時候會去加載他。

在MyConfiguration中我們可以看到有一個方法返回的是一個MyBean的實例,並且該方法上標注着@Bean的注解,標明這是一個注入Bean的方法,會將下面的返回的Bean注入IOC。

通過構造方法注入Bean

我們在生成一個Bean實例的時候,可以使用Bean的構造方法將Bean實現注入。直接看代碼

Bean類

@Component
public class MyBeanConstructor {

 private AnotherBean anotherBeanConstructor;

 @Autowired
 public MyBeanConstructor(AnotherBean anotherBeanConstructor){
     this.anotherBeanConstructor = anotherBeanConstructor;
 }

 @Override
 public String toString() {
     return "MyBean{" +
         "anotherBeanConstructor=" + anotherBeanConstructor +
         '}';
 }
}

AnotherBean類

@Component(value="Bean的id,默認為類名小駝峰")
public class AnotherBean {
}

Configuration類

@Configuration
@ComponentScan("com.company.annotationbean")
public class MyConfiguration{
}

這里我們可以發現,和一般方式注入的代碼不一樣了,我們來看看新的注解都是什么意思:

@AutoWired

簡單粗暴,直接翻譯過來的意思就是自動裝配🔧,還不理解為什么叫自動裝配🔧?看了下一個注解的解釋你就知道了。若是在這里注入的時候指定一個Bean的id就要使用@Qualifier注解

@Component(默認單例模式)

什么??這翻譯過來是零件,怎么感覺像是修汽車??是的,Spring管理Bean的方法就是修汽車的方式。我們在需要將一個類變成一個Bean被Spring可以注入的時候加上注解零件@Conmonent,那么我們就可以在加載Bean的時候把他像零件一樣裝配🔧到這個IOC汽車上了

在這里我們還有幾個其他的注解也可以實現這個功能,也就是細化的@Component

  • @Controller 標注在Controller層
  • @Service 標注在Service層
  • @Repository 標注在dao層

@ComponentScan("")

還是翻譯,零件掃描,我們去看看括號里的“零件倉庫”里面,哪些“零件”(類)需要被裝載,Spring就會去掃描這個包,將里面所有標注了@Component的類進行注入。

這里的通過構造方法進行注入就很好理解了,我們在裝配MyBean這個零件的時候,突然發現他必須在AnotherBean的基礎上才能安裝到IOC里面,那么我們就在每次裝配MyBean的時候自動裝配🔧一個AnotherBean進去。舉個🌰吧:

還是以汽車為例,我們在踩油門出發之前,是不是必須發車??這里的AutoWired的內容就像發車,你不發車,這個油門你踩斷都沒有用,他都不會走。

通過set方法注入Bean

我們可以在一個屬性的set方法中去將Bean實現注入,看代碼吧

MyBean類

@Component
public class MyBeanSet {

 private AnotherBean anotherBeanSet;

 @Autowired
 public void setAnotherBeanSet(AnotherBean anotherBeanSet) {
     this.anotherBeanSet = anotherBeanSet;
 }

 @Override
 public String toString() {
     return "MyBeanSet{" +
         "anotherBeanSet=" + anotherBeanSet +
         '}';
 }
}

Configuration類 和 Test類

同上一個,就不貼了

這里我們發現在setter方法上我們有一個@AutoWired,與上面不同的是,我們不會在實例化該類時就自動裝配🔧這個對象,而是在顯式調用setter的時候去裝配。

通過屬性去注入Bean

我們前面兩種注入的方式諸如時間不同,並且代碼較多,若是通過屬性,即就是

@Component
public class MyBeanProperty {

 @Autowired
 private AnotherBean anotherBeanProperty;

 @Override
 public String toString() {
     return "MyBeanProperty{" +
         "anotherBeanProperty=" + anotherBeanProperty +
         '}';
 }
}

這里我們可以看到我們這個類中需要使用AnotherBean這個實例對象,我們可以通過@AutoWired去自動裝配它。

對於有些小伙伴問私有屬性,Spring怎么去加載它到IOC的?推薦去看看反射

通過List注入Bean

MyBeanList類

@Component
public class MyBeanList {

 private List<String> stringList;

 @Autowired
 public void setStringList(List<String> stringList) {
     this.stringList = stringList;
 }

 public List<String> getStringList() {
     return stringList;
 }
}

MyConfiguration類

@Configuration
@ComponentScan("annoBean.annotationbean")
public class MyConfiguration {

    @Bean
    public List<String> stringList(){
       List<String> stringList = new ArrayList<String>();
       stringList.add("List-1");
       stringList.add("List-2");
       return stringList;
    }
}

這里我們將MyBeanList進行了注入,對List中的元素會逐一注入。下面介紹另一種方式注入List

MyConfiguration類

@Bean
//通過該注解設定Bean注入的優先級,不一定連續數字
@Order(34)
public String string1(){
    return "String-1";
}

@Bean
@Order(14)
public String string2(){
    return "String-2";
}

注入與List中泛型一樣的類型,會自動去匹配類型,及時這里沒有任何List的感覺,只是String的類型,但他會去通過List的Bean的方式去注入。

第二種方式的優先級高於第一種,當兩個都存在的時候,若要強制去使用第一種方式,則要去指定Bean的id即可

通過Map去注入Bean

@Component
public class MyBeanMap {

 private Map<String,Integer> integerMap;

 public Map<String, Integer> getIntegerMap() {
     return integerMap;
 }

 @Autowired
 public void setIntegerMap(Map<String, Integer> integerMap) {
     this.integerMap = integerMap;
 }
}
@Bean
public Map<String,Integer> integerMap(){
    Map<String,Integer> integerMap = new HashMap<String, Integer>();
    integerMap.put("map-1",1);
    integerMap.put("map-2",2);
    return integerMap;
}

@Bean
public Integer integer1(){
    return 1;
}

@Bean
public Integer integer2(){
    return 2;
}

同樣這里也具有兩種方式去注入Map類型Bean,且第二種的優先值高於第一種

以上就是Bean通過注解注入的幾種方式,大家可以對比着xml注入的方式去看。

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協程要來了。。。

3.Spring Boot 2.x 教程,太全了!

4.20w 程序員紅包封面,快快領取。。。

5.《Java開發手冊(嵩山版)》最新發布,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM