真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Spring構(gòu)造函數(shù)注入方式詳解

??本文講解spirng三種注入方式(構(gòu)造函數(shù)注入,setter注入,注解注入)中的構(gòu)造函數(shù)注入。

成都創(chuàng)新互聯(lián)專注于二七企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,成都做商城網(wǎng)站。二七網(wǎng)站建設(shè)公司,為二七等地區(qū)提供建站服務(wù)。全流程按需網(wǎng)站制作,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)

??所有例子,都是以注解的方式注冊(cè)bean。

??關(guān)于構(gòu)造函數(shù)方式注入,spring官網(wǎng)的說(shuō)明地址為:Spring官網(wǎng)之構(gòu)造函數(shù)注入

1. 構(gòu)造函數(shù)只有一個(gè)參數(shù)且類型為單個(gè)實(shí)現(xiàn)類

單參數(shù)且單實(shí)現(xiàn)類這是一種最簡(jiǎn)單的以構(gòu)造函數(shù)的注入方式注入依賴,只要在構(gòu)造函數(shù)中添加所依賴類型的參數(shù)即可,spring會(huì)匹配對(duì)應(yīng)類型的bean進(jìn)行注入,由于只有一個(gè)對(duì)應(yīng)類型的實(shí)現(xiàn)類,因此能準(zhǔn)確地找到bean進(jìn)行注入。

我們看以下例子:

  • 創(chuàng)建一個(gè)接口:
public interface GoPlay {

    public void havePlay();
}
  • 創(chuàng)建一個(gè)實(shí)現(xiàn)類
import org.springframework.stereotype.Component;

@Component
public class GoPlayImpl implements GoPlay {
    @Override
    public void havePlay() {
        System.out.println("\n\nsingle play\n\n");
    }
}
  • 再創(chuàng)建一個(gè)具體類,依賴于GoPlay接口,以構(gòu)造函數(shù)方式注入:
import org.springframework.stereotype.Component;

@Component
public class PlayController {
    private GoPlay goPlay;

    public PlayController(GoPlay goPlay) {
        this.goPlay = goPlay;
    }

    public void play(){
        goPlay.havePlay();
    }
}
  • 用單元測(cè)試驗(yàn)證一下是否能將GoPlay唯一的實(shí)現(xiàn)類注入到PlayController中:
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

@RunWith(SpringRunner.class)
@SpringBootTest
public class PlayControllerTest {
    @Resource
    PlayController playController;

    @After
    public void tearDown() throws Exception {
    }

    @Test
    public void play() {
        playController.play();

    }
}

//有一些自動(dòng)生成的函數(shù)沒(méi)有刪除

  • 執(zhí)行測(cè)試用例,執(zhí)行結(jié)果打印如下:
single play

說(shuō)明成功地將對(duì)應(yīng)的bean以構(gòu)造函數(shù)的方式注入。

2. 參數(shù)依賴類型有多實(shí)現(xiàn)類情況下的注入方式

單構(gòu)造函數(shù)參數(shù)依賴的類型,有多個(gè)實(shí)現(xiàn)類時(shí),就不能直接像上面的例子一樣,只定義接口的類型了:

以下方式是錯(cuò)誤的:

public MorePlayContorller(MorePlay morePlay) {
morePlay.someOnePlay();
}

需要寫(xiě)明所引用的bean的名稱,否則spring根據(jù)type匹配到兩個(gè)bean,就會(huì)報(bào)錯(cuò)。

看下實(shí)際的例子:

  • 聲明一個(gè)接口:
    public interface MorePlay {
    public void someOnePlay();
    }
  • 第一個(gè)實(shí)現(xiàn)類:
import org.springframework.stereotype.Component;

@Component
public class MorePlayImplFirstOne implements MorePlay {
    @Override
    public void someOnePlay() {
        System.out.println("\n\nFirst one play.\n\n");
    }
}
  • 第二個(gè)實(shí)現(xiàn)類:
import org.springframework.stereotype.Component;

@Component
public class MorePlayImplSecondOne implements MorePlay {
    @Override
    public void someOnePlay() {
        System.out.println("\n\nSecond one play.\n\n");
    }
}
  • 以構(gòu)造函數(shù)方式注入以上定義類型(下面這個(gè)例子會(huì)注入失敗):
import org.springframework.stereotype.Component;

@Component
public class MorePlayContorller {

    private MorePlay morePlay;

    public MorePlayContorller(MorePlay morePlay) {
        morePlay.someOnePlay();
    }

}
  • 寫(xiě)一個(gè)測(cè)試用例驗(yàn)證一下:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

@RunWith(SpringRunner.class)
@SpringBootTest
public class MorePlayContorllerTest {
    @Resource MorePlayContorller morePlayContorller;

    @Test
    public void play() {
        morePlayContorller.play();
    }
}
  • 執(zhí)行結(jié)果如下(堆棧這里就不貼了,看一下具體的報(bào)錯(cuò)):
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.example.springbootexample.oneArgument.MultiImplementation.MorePlay' available: expected single matching bean but found 2: morePlayImplFirstOne,

很顯然,直接就懵圈了,我找到了兩個(gè),你是想要哪一個(gè)?實(shí)際上,這種方式編譯都過(guò)不了。

  • 正確的方式:用Qualifier指定具體的bean name,或者構(gòu)造函數(shù)中的屬性名與所要注入的bean名稱一致。
    方式一:用Qualifier指定具體的bean name
@Component
public class MorePlayContorller {

    private MorePlay morePlay;

    public MorePlayContorller(@Qualifier("morePlayImplFirstOne") MorePlay morePlay) {
        this.morePlay = morePlay;
    }

    public void play(){
        morePlay.someOnePlay();
    }

}

方式二:構(gòu)造函數(shù)中的屬性名與所要注入的bean名稱一致


import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class MorePlayContorller {

    private MorePlay morePlay;

    public MorePlayContorller(@Qualifier("morePlayImplFirstOne") MorePlay morePlay) {
        this.morePlay = morePlay;
    }

    public void play(){
        morePlay.someOnePlay();
    }

}
  • 以上兩種方式都正確注入,再執(zhí)行測(cè)試用例,就能執(zhí)行成功了:
First one play

3. list注入方式

當(dāng)具體業(yè)務(wù)場(chǎng)景中,需要依賴于某接口的所有實(shí)現(xiàn)類時(shí),可以使用list注入,構(gòu)造函數(shù)方式注入,同樣也可以注入list。

  • 接口和實(shí)現(xiàn)類,我們繼續(xù)沿用MorePlay及其實(shí)現(xiàn)。

  • 依賴的類定義如下:
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class ListPlayControler {

    private List goPlays;

    public ListPlayControler(List goPlays) {
        this.goPlays = goPlays;
    }

    public void listPlay(){
        goPlays.forEach(goPlay -> goPlay.someOnePlay());
    }

}
  • listPlay方法會(huì)執(zhí)行GoPlay接口所有實(shí)現(xiàn)類對(duì)方法havePlay()的重寫(xiě)。list的注入方式易于業(yè)務(wù)的擴(kuò)展,封裝的代碼不會(huì)因?yàn)閿U(kuò)展了一個(gè)新的實(shí)現(xiàn)類而發(fā)生改動(dòng),完全遵循了設(shè)計(jì)模式的原則。

  • 用測(cè)試用例驗(yàn)證一下:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ListPlayControlerTest {

    @Resource private ListPlayControler listPlayControler;

    @Test
    public void listPlay() {
        listPlayControler.listPlay();
    }
}
  • 執(zhí)行結(jié)果符合預(yù)期:
First one play.

Second one play.

4. 構(gòu)造函數(shù)多參數(shù)依賴情況下的注入方式

  • 需要依賴多接口的場(chǎng)景很多,這個(gè)時(shí)候仍然可以使用構(gòu)造函數(shù)的注入方式。

  • 我們創(chuàng)建一個(gè)類,使他依賴于本文中創(chuàng)建的兩個(gè)接口:
import com.example.springbootexample.oneArgument.MultiImplementation.MorePlay;
import com.example.springbootexample.oneArgument.SingleImplementation.GoPlay;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class PlayMoreArugumentContoller {
    private GoPlay goPlay;
    private MorePlay morePlay;

    public PlayMoreArugumentContoller(GoPlay goPlay, @Qualifier("morePlayImplSecondOne") MorePlay morePlay) {
        this.goPlay = goPlay;
        this.morePlay = morePlay;
    }

    public void playAll(){
        goPlay.havePlay();
        morePlay.someOnePlay();

    }
}
  • 創(chuàng)建測(cè)試用例驗(yàn)證一下,執(zhí)行成功,能夠成功注入對(duì)應(yīng)的bean:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

@RunWith(SpringRunner.class)
@SpringBootTest
public class PlayMoreArugumentContollerTest {

    @Resource private PlayMoreArugumentContoller playMoreArugumentContoller;

    @Test
    public void playAll() {
        playMoreArugumentContoller.playAll();
    }
}
  • 執(zhí)行結(jié)果符合預(yù)期:
single play

Second one play.

文章名稱:Spring構(gòu)造函數(shù)注入方式詳解
文章出自:http://weahome.cn/article/jpchhh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部