@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