Spring Boot 注入介面 @Autowired interface

weixin_33797791發表於2017-04-11

前言:@Service @Component @Configuration 注入方式相同

介面只有唯一一個實現類的注入方式

先建立一個介面VideoService

public interface VideoService {

   String getVideoName();

}

建立一個介面的實現類VideoServiceImpl,使用@Service註解

@Service
public class VideoServiceImplA implements VideoService {

  @Override
  public String getVideoName() {
    return "三生三世十里桃花";
  }

}

在其他類中注入VideoService,此處以一個Controller類示例:

@RestController
public class HomeController {

  @Autowired
  private VideoService videoService;

  @RequestMapping("/video")
  public String videoName(){
    return videoService.getVideoName();
  }

}

訪問 http://localhost/video 正常,結果如下:

3424642-0d622f7c672671a9.png
訪問結果

具體注入詳情如下(需新增spring-boot-starter-actutor):


3424642-a757b6021cf4b621.png
對應介面注入的Bean

介面有多個實現類的注入方式

新增一個VideoService的實現類VideoServiceImplB:

@Service
public class VideoServiceImplB implements VideoService{

  @Override
  public String getVideoName() {
    return "人民的名義";
  }

}

重啟專案結果如下:

3424642-92ffe188e5e7c156.png
多個實現類情況

Spring給了明確提示說有2個Bean被找到,但是隻需要一個。建議使用@Primary註解使其優先被選擇,或者使用@Qualifier指定注入一個Bean。

先看第一種@Primary註解,在VideoServiceImplB上新增@Primary註解:

@Service
@Primary
public class VideoServiceImplB implements VideoService{

  @Override
  public String getVideoName() {
    return "人民的名義";
  }

}

重啟專案->正常啟動。訪問 http://localhost/video 結果如下:

3424642-06d166c7dcfce3e1.png
@Primary註解VideoServiceImplB

HomeController中注入的也是videoServiceImplB:

3424642-9d63ee3c877873a6.png
被注入的videoService

總結:使用@Primary註解的實現類會被優先注入

再來看看@Qualifier註解,去掉VideoServiceImplB的@Primary註解,改寫HomeController的程式碼:

@RestController
public class HomeController {

  @Autowired
  @Qualifier("videoServiceImplB")
  private VideoService videoService;

  @RequestMapping("/video")
  public String videoName(){
    return videoService.getVideoName();
  }

}

重啟專案,結果和上面一樣,說明注入的videoService是videoServiceImplB。

總結:使用@Qualifier注入指定Bean的時候,若沒有指明Bean的名稱,則其預設名稱是首字母小寫的類名。

那麼如何指定Bean的名稱呢?看看@Service的程式碼:

3424642-c33952d91f1508cc.png
@Service

此處的value值即為bean的名稱,使用時將 @Service 改為 @Service("bean名稱") 即可。注入時使用 @Qualifier("bean名稱")

看看效果:

@Service("videoB")
public class VideoServiceImplB implements VideoService{

  @Override
  public String getVideoName() {
    return "人民的名義";
  }

}

@RestController
public class HomeController {

  @Autowired
  @Qualifier("videoB")
  private VideoService videoService;

  @RequestMapping("/video")
  public String videoName(){
    return videoService.getVideoName();
  }

}

3424642-f524018d88d42b7c.png
指定Bean名稱

相關文章