@Autowired的依賴注入的兩種方式


@Autowired 被動注入形式有兩種,一種是 bytype 另外一種是 byname,默認的方式是 bytype,Spring 會去容器中根據接口類型去尋找實現的 Bean,那么會有以下幾種情況:

  1. 找不到任何一個 Bean
  2. 只有一個實現的 Bean
  3. 找到多個實現類

我們分別對看下這三種情況

找不到任何一個實現類

  • 定義一個 ISkill 接口
public interface ISkill {
    void r();
}
  • controller 中注入該接口
@RestController
@RequestMapping("/v1/banner")
public class BannerController {

    @Autowired
    private ISkill iSkill;

    @GetMapping("/test")
    public String test() {
        iSkill.r();
        return "Hello China";
    }
}

這時Idea會直接提示報錯: Could not autowire. No beans of 'ISkill' type found.

只有一個實現類

  • 定義一個實現類
@Component
public class Hero1 implements ISkill {

    public Hero1() {
        System.out.println("實例化Hero1對象");
    }

    @Override
    public void r() {
        System.out.println("Hero1......");
    }
}

如果只有一個的情況下,會直接注入到容器中,不會有任何的影響。

有多個實現類

@Component
public class Hero1 implements ISkill {

    public Hero1() {
        System.out.println("實例化Hero1對象");
    }

    @Override
    public void r() {
        System.out.println("Hero1......");
    }
}
@Component
public class Hero2 implements ISkill {

    public Hero2() {
        System.out.println("實例化Hero1對象");
    }

    @Override
    public void r() {
        System.out.println("Hero2......");
    }
}

這個是如果我們在 Controller 中如果注入的類的名稱不是任何一個實現類的名稱,依然報錯 Could not autowire. There is more than one bean of 'ISkill' type.

@RestController
public class BannerController {

    @Autowired
    private ISkill iSkill;

    @GetMapping("/test")
    public String test() {
        iSkill.r();
        return "Hello China";
    }
}

但是如果將 iSkill 的名稱修改為 hero1 或者 hero2 都不會報錯

@RestController
public class BannerController {

    @Autowired
    private ISkill hero1; // 或者這里名稱叫做 hero2

    @GetMapping("/test")
    public String test() {
        hero1.r();
        return "Hello China";
    }
}

出現這種的原因就是因為,Spring 會根據 ISkill 接口的類型去推導實現,如果有多個實現的話,會根據具體的名稱去判斷,但是如果名稱也不對的話,那么Spring是不會知道該如果注入,因此會報錯。只需要修改名稱即可。

那么如果我們不想修改名稱怎么辦呢?就需要使用 @Autowired 的主動注入,也就是添加一個 @Qualifier 注解

@RestController
public class BannerController {

    @Autowired
    @Qualifier(value = "hero1")
    private ISkill iSkill;

    @GetMapping("/test")
    public String test() {
        iSkill.r();
        return "Hello China";
    }
}


免責聲明!

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



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