@Autowired
可以用在字段或者setter方法上或者构造器上。
@autowired写在变量上的注入要等到类完全加载完,才会将相应的bean注入。
写在方法上是为了在构造方法中使用到该变量。写到构造方法中,也就是有了先后的注入依赖关系
建议一:
优先选择@Autowired
注入,而不是@Resource
注入原理:@Autowired
会先按类型注入,然后按照名称注入,都无法找到唯一的一个实现类则报错。这于@Resource
相反
建议二:
@Autowired
最好与@Qualifier()
一起使用,不要图省事,虽然大多数情况下只用@Autowired
就可以正常注入
建议三:
@Autowired
可以用在字段或者setter方法上或者构造器上。
但是不推荐用在字段上,容易发生空指针错误,推荐使用在构造器或者setter方法上,如下:
- 使用字段注入容易发生空指针异常
下面的代码只做演示,实际开发中不会这样写
@RestController
public class PersonController {
@Autowired
@Qualifier("personService")
private PersonService personService;
private String name;
// 构造方法
public PersonController() {
this.name = personService.getName(); // 这里会报空指针异常
}
}
原因是构造方法先于@Autowired被初始化。
PS:Java变量的初始化顺序为:静态变量或静态语句块 –> 实例变量或初始化语句块 –> 构造方法 –> @Autowired
- 在构造器上使用:
优点:
①可以防止上面所说的空指针异常
②可以明确成员变量的加载顺序
下面是官方推荐的写法:
@RestController
public class PersonController {
private final PersonService personService;
/**
* Spring Team建议:“始终在bean中使用基于构造函数的依赖注入。始终使用断言来强制依赖”。
*/
@Autowired
public PersonController(@Qualifier("personService") PersonService personService){
Assert.notNull(personService, "personService must not be null");
this.personService = personService;
}
}
- 在setter方法上使用
@RestController
public class PersonController {
private PersonService personService;
@Autowired
@Qualifier("personService")
public void setPersonService(PersonService personService) {
this.personService = personService;
}