使用@Autowired注入的bean对于目标类来说,从代码结构上来讲也就是一个普通的成员变量,@Autowired和spring一起工作,通过反射为这个成员变量赋值,也就是将其赋为期望的类实例。
1.一个实现类、注入同类型
@Service public class HelloServiceImpl implements HelloService { @Override public void sayHello() { System.out.println("say hello impl"); } }
@Autowired private HelloService helloService; 或者 @Autowired private HelloService abc;
结果 注入成功
@Autowired 第一是按照类型去匹配的,此时IoC容器中HelloService 接口只有一个实现类,所以属性名字怎么写都没关系,都可以注入进去
2.多个实现类、注入同类型
再增加一个实现类
@Service public class NewHelloServiceImpl implements HelloService { @Override public void sayHello() { System.out.println("new say hello impl"); } }
@Autowired private HelloService abc;
结果注入失败
因为一个接口有多个实现,所以@Autowired 就按照属性名字去找,即找一个名字为 abc的bean注入,然而IoC容器不存在一个名字叫abc的 bean,因此报错,把属性名改为下面任意一种就可以匹配到了
@Autowired private HelloService helloServiceImpl; @Autowired private HelloService newHelloServiceImpl;
3.多个实现类、注入同类型、指定固定属性名称
1.注入对象不变,改实现类
@Service("abc")--修改这个 public class HelloServiceImpl implements HelloService { @Override public void sayHello() { System.out.println("say hello impl"); } }
@Autowired private HelloService abc;
注入成功了
或者
2.实现类不变,改注入对象
@Service public class HelloServiceImpl implements HelloService { @Override public void sayHello() { System.out.println("say hello impl"); } }
@Autowired @Qualifier("helloServiceImpl")--增加这个 private HelloService abc;
总结:
1.一个接口只有一个实现的情况下,属性名字怎么写都无所谓,因为按照类型匹配就只有一个bean
2.一个接口多个实现的情况下:
① 属性名字跟组件名字一致,组件名字可以在声明的时候指定,比如 @Service("abc")
② 属性名字跟组件名字不一致,配合@Qualifier 注解指定组件名字