@Autowired 注解属于 org.springframework.beans.factory. annotation 包,可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。
@Service 注解属于 org.springframework.stereotype 包,会将标注类自动注册到 Spring 容器中。
在一个类上面标注@Service或者@Controller或@Component或@Repository注解后,容器启动时,Spring组件扫描时就会发现它,并且会直接将其创建好变成Spring应用上下文中bean。
在需要使用时通过@Autowired注解把容器创建好的bean从容器获取过来赋予给使用类的成员属性
@Autowired注解的注入规则
默认根据类型,存在多个时则根据名字进行匹配
public interface User {
void hello();
}
@Service
public class Userimpl implements User{
@Override
public void hello(){
System.out.println("hello");
}
}
@Controller
public class HelloController {
@Autowired
private User user;
public void hello(){
user.hello();
}
}
@SpringBootTest
class SbPack2ApplicationTests {
private HelloController helloController;
@Autowired
public SbPack2ApplicationTests (HelloController helloController)
{
this.helloController=helloController;
}
@Test
void contextLoads() {
helloController.hello();
}
}
@Service
public class NewUserimpl implements User{
@Override
public void hello(){
System.out.println("hello");
}
}
那么Controller里面就会出现报错,此时IoC容器中HelloService 接口存在两个实现类,自动装配决定不了使用哪一个实现类,会像下图一样报错
这时候就需要用到一个新的注解
@Qualifier是指定 一个bean的名字
作用就是解决当使用@Autowired遇到多个实现类时的问题
现在我们可以尝试
@Controller
public class HelloController {
@Qualifier("newUserimpl") //这里并不是和实现类名完全相同,应该有自己的命名规则
@Autowired
private User newuser;
@Qualifier("userimpl")
@Autowired
private User user;
public void hello(){
user.hello();
newuser.hello();
}
}
输出结果如下
又或者当出现多个实现类时我们还可以这样做,在service注解处直接标明限定符
@Service("abs")
public class Userimpl implements User{
@Override
public void hello(){
System.out.println("hello");
}
}
@Service("abd")
public class NewUserimpl implements User{
@Override
public void hello(){
System.out.println("new hello");
}
}
那么在Controller中使用时就可以不用加上@Qualifier注解
而是让属性名直接就是限定符
@Controller
public class HelloController {
@Autowired
private User abs;
@Autowired
private User abd;
public void hello(){
abs.hello();
abd.hello();
}
}
同样也能正常输出
@Controller
public class HelloController {
@Autowired
private User abs;
@Autowired
private User abd;
@Qualifier("abd")
@Autowired
private User abd1;
public void hello(){
abs.hello();
abd.hello();
abd1.hello();
}
}
输出变成
@Service("abs")
public class Userimpl implements User{
public Userimpl(){
System.out.println("hello user");
}
@Override
public void hello(){
System.out.println("hello");
}
}
可以看见构造参数的输出是最先出现的