Springboot笔记<4>@Autowired和@Resource的区别

@Autowired和@Resource的区别

@Resource

有两个常用属性name、type,所以分4种情况

  1. 指定name和type:通过name找到唯一的bean,找不到抛出异常;如果type和字段类型不一致,也会抛出异常
  2. 指定name:通过name找到唯一的bean,找不到抛出异常
  3. 指定type:通过tpye找到唯一的bean,如果不唯一,则抛出异常:NoUniqueBeanDefinitionException
  4. 都不指定:通过字段名作为key去查找,找到则赋值;找不到则再通过字段类型去查找,如果不唯一,则抛出异常:NoUniqueBeanDefinitionException

@Autowired

@Autowired由Spring提供,只按照byType注入

@Autowired只有一个属性required,默认值为true,为true时,找不到就抛异常,为false时,找不到就赋值为null

@Autowired按类型查找,如果该类型的bean不唯一,则抛出异常;可通过组合注解解决@Autowired()@Qualifier("baseDao")

相同点

  1. Spring都支持
  2. 都可以作用在字段和setter方法上

不同点

  1. Resource是JDK提供的,而Autowired是Spring提供的
  2. Resource不允许找不到bean的情况,而Autowired允许(@Autowired(required = false)
  3. 指定name的方式不一样,@Resource(name = "baseDao"),@Autowired()@Qualifier("baseDao")
  4. Resource默认通过name查找,而Autowired默认通过type查找

总结

@Autowired自动注解,一个类,俩个实现类,Autowired就不知道注入哪一个实现类,需要配合@Qualifier按照name注入,而Resource有name属性,可以区分。

举例说明

@Autowired

在service层,让StudentServiceImpl1,StudentServiceImpl2实现StudentService借口

在controller层,使用@Autowired注入则会抛出异常,idea直接提示使用@Qualifier进行区分,解决方案有四种:

1:@Autowired+@Qualifier("studentServiceImpl1")则可以进行区分

2:去掉一个StudentService的实现类,则可以直接按照类型进行装配

3:**@Autowired+@Primary****,自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常。(只对接口的多个实现生效)

4: @Resource(name = "studentServiceImpl1"),不指定name会抛出异常。如果只有StudentServiceImpl1,删掉StudentServiceImpl2,则可以直接使用@Resource,根据类型查找唯一值

@Service
public class StudentServiceImpl1 implements StudentService {

    @Override
    public void getStudentAge() {
        System.out.println("查到学生的年龄");
    }
}

@Service
public class StudentServiceImpl2 implements StudentService {

    @Override
    public void getStudentAge() {
        System.out.println("查到学生的年龄");
    }
}


错误写法:

@Slf4j
@RestController
public class StudentController {
    @Autowired
    StudentService studentService;
    @RequestMapping("/student")
    public String handle01(){
        studentService.getStudentAge();
        return "student";
    }
}

正确的@Autowired+@Qualifier写法:

@Slf4j
@RestController
public class StudentController {
    @Autowired
    @Qualifier("studentServiceImpl1")
    StudentService studentService;
    @RequestMapping("/student")
    public String handle01(){
        studentService.getStudentAge();
        return "student";
    }
}

正确的@Autowired+@Primary写法:

@Service
@Primary
public class StudentServiceImpl1 implements StudentService {
    @Override
    public void getStudentAge() {
        System.out.println("查到学生的年龄");
    }
}

正确的@Resource写法:

@Slf4j
@RestController
public class StudentController {
    @Resource(name = "studentServiceImpl1")
    StudentService studentService;
    @RequestMapping("/student")
    public String handle01(){
        studentService.getStudentAge();
        return "student";
    }
}
posted @ 2021-12-21 14:19  aixueforever  阅读(264)  评论(0编辑  收藏  举报