1、@Autowired
自动注入:
- 默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);找到就赋值
- 如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找applicationContext.getBean(“bookDao”)
举例说明:我们在BookService里使用@Autowired注入BookDao,并在容器中注入两个BookDao,测试如下:
向容器中加入BookDao,类型为BookDao,id为bookDao;lable值默认为1
//名字默认是类名首字母小写
@Repository
public class BookDao {
private String lable = "1";
public void setLable(String lable) {
this.lable = lable;
}
@Override
public String toString() {
return "BookDao [lable=" + lable + "]";
}
}
向容器中加入BookDao,类型为BookDao,id为bookDao2;lable值设置为2,为了和上面注入的BookDao做区分
@Configuration
@ComponentScan({"com.*"})
public class AutowiredConfig {
@Bean(name = "bookDao2")
public BookDao bookDao(){
BookDao bookDao = new BookDao();
bookDao.setLable("2");
return bookDao;
}
}
BookService中注入BookDao
@Service
public class BookService {
@Autowired
private BookDao bookDao;
@Override
public String toString() {
return "BookService [bookDao=" + bookDao + "]";
}
}
测试类
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AutowiredConfig.class);
BookService bookService = applicationContext.getBean(BookService.class);
System.out.println("bookService->"+bookService);
}
输出如下:
bookService->BookService [bookDao=BookDao [lable=1]]
当我们将BookService中注入的bookDao改为bookDao2,如下:
@Service
public class BookService {
@Autowired
private BookDao bookDao2;
@Override
public String toString() {
return "BookService [bookDao=" + bookDao2 + "]";
}
}
输出结果:
bookService->BookService [bookDao=BookDao [lable=2]]
可见,如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找,也就验证了我们上面的第二点。
其他:
当@Autowired注入的bean没有加入到容器中,启动时会报NoSuchBeanDefinitionException
异常,可以指定@Autowired(required = false),启动时不去检查@Autowired的bean是否加入到容器中
2、@Qualifier
使用@Qualifier指定需要装配的组件的id,而不是使用属性名
当容器中存在多个type类型相同的bean,可以使用@Qualifier注解,会按组件id装配,使用如下:
当我们将BookService中注入的BookDao加入@Qualifier(“bookDao”)时:
@Service
public class BookService {
@Qualifier("bookDao")
@Autowired
private BookDao bookDao2;
@Override
public String toString() {
return "BookService [bookDao=" + bookDao2 + "]";
}
}
输出如下:
bookService->BookService [bookDao=BookDao [lable=1]]
虽然我们注入的BookDao属性名为bookDao2,但加入@Qualifier(“bookDao”)后,容器会优先找id=bookDao的bean,也就是注入了lable=1的BookDao。
3、@Primary
让Spring进行自动装配的时候,默认使用首选的bean;
我们还原bookService
@Service
public class BookService {
@Autowired
private BookDao bookDao;
@Override
public String toString() {
return "BookService [bookDao=" + bookDao + "]";
}
}
此时加载的为bookDao1;当我们将bookDao2上加入@Primary注解,那么@Autowired会优先装配
@Primary
@Bean(name = "bookDao2")
public BookDao bookDao(){
BookDao bookDao = new BookDao();
bookDao.setLable("2");
return bookDao;
}
输出如下:
bookService->BookService [bookDao=BookDao [lable=2]]
当我们在BookService再次加入@Qualifier(“bookDao”),强制使用bookDao
@Service
public class BookService {
@Qualifier("bookDao")
@Autowired
private BookDao bookDao;
@Override
public String toString() {
return "BookService [bookDao=" + bookDao + "]";
}
}
输出如下:
bookService->BookService [bookDao=BookDao [lable=1]]
也就是说@Primary可以与@Qualifier一起使用,@Qualifier优先级会大于@Primary
4、@Resource
- 可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的;
- 没有能支持@Primary功能,没有支持@Autowired(reqiured=false)功能;
使用如下:
@Service
public class BookService {
@Resource
private BookDao bookDao;
@Override
public String toString() {
return "BookService [bookDao=" + bookDao + "]";
}
}
输出如下:
bookService->BookService [bookDao=BookDao [lable=1]]
当@Resource(name = “bookDao2”),则会装配bookDao2
5、@Autowired使用范围
- 标注在方法位置
- 标在构造器上
- 放在参数位置
1、标注在方法上,spring容器创建当前对象,会调用该方法,完成赋值;方法参数Student从容器中获取
@Service
public class BookService {
private Student student;
@Autowired
public void setStudent(Student student){
this.student = student;
}
}
2、标注在构造器上,spring容器创建当前对象会调用该构造方法,方法参数Student从容器中获取
@Service
public class BookService {
@Autowired
public BookService(Student student){
this.student = student;
}
}
3、标注在参数上与标注在方法上效果一样
@Service
public class BookService {
private Student student;
public void setStudent(@Autowired Student student){
this.student = student;
}
}
总结:@Autowired与@Resource区别
- @Autowired是spring的,@Resource是java的
- @Resource不能跟@Qualifier、@Primary配合使用,也没有require=false属性
- @Autowired默认按类型装配,@Resource默认按组件名称装配