Spring中被放棄的@Autowired,你會(huì)用嗎?
注入方式一:屬性(字段)注入
在某個(gè)屬性(字段)上使用@Autowired注解時(shí),Spring在創(chuàng)建該Bean的過(guò)程中,會(huì)根據(jù)字段的類型或名稱從Spring容器中查找到所匹配的Bean對(duì)象,并賦值給該熟悉。
@Service
public class UserService {
// 注入方式一:屬性注入
@Autowired
private RoleService roleService;
public void printRoleService() {
System.out.println(roleService);
}
}
注入方式二:Setter注入
在某個(gè)Setter方法上使用@Autowired注解時(shí),Spring在創(chuàng)建該Bean的過(guò)程中,會(huì)來(lái)調(diào)用該Setter方法,并且如果Set方法有入?yún)?shù),那么Spring會(huì)格局入?yún)?shù)信息,從Spring容器中找到所匹配的Bean對(duì)象賦值給該入?yún)ⅰN覀兺ㄟ^(guò)再Setter方法中給屬性賦值,從而就達(dá)到了Setter方法注入的目的。
@Service
public class UserService {
private RoleService roleService;
public void printRoleService() {
System.out.println(roleService);
}
public RoleService getRoleService() {
return roleService;
}
// 注入方式二:Setter注入
@Autowired
public void setRoleService(RoleService roleService) {
this.roleService = roleService;
}
}
注意:@Autowired注解其實(shí)可以添加在任何一個(gè)普通方法上,不一定是Setter方法。
注入方式三:構(gòu)造函數(shù)注入
當(dāng)某個(gè)構(gòu)造方法上使用@Autowired注解時(shí),表示該Bean在創(chuàng)建時(shí)會(huì)使用這個(gè)構(gòu)造方法來(lái)實(shí)例化得到一個(gè)對(duì)象,并且Spring會(huì)根據(jù)該構(gòu)造函數(shù)的入?yún)?shù)的類型和名字,從Spring容器中找到所匹配的Bean對(duì)象傳給該入?yún)ⅲㄟ^(guò)在構(gòu)造函數(shù)中給屬性賦值,從而就達(dá)到了構(gòu)造函數(shù)注入的目的。
@Service
public class UserService {
private RoleService roleService;
// 注入方式三:構(gòu)造函數(shù)注入
@Autowired
public UserService(RoleService roleService) {
this.roleService = roleService;
}
public void printRoleService() {
System.out.println(roleService);
}
}
注入方式四:參數(shù)注入
盡管@Autowired注解可以加在普通方法或構(gòu)造方法的參數(shù)之前,但是Spring框架中大部分地方都忽略了這種情況下的@Autowired注解,僅僅在spring-test模塊中的對(duì)于JUnit Jupiter的支持中,支持了參數(shù)前添加@Autowired。
@SpringBootTest(classes = ConstructorAttributeMain.class)
class UserServiceTest {
@Test
void printRoleService(@Autowired UserService userService) {
userService.printRoleService();
}
}
required屬性釋義
- required=true:默認(rèn)值,必須存在Bean,否則報(bào)錯(cuò)
- required=false:若找不到Bean,則為空
@Service
public class UserService {
@Autowired(required = true)
private RoleService roleService;
@Autowired(required = false)
private MenuService menuService;
public void print() {
System.out.println("role: " + roleService); // print class
System.out.println("menu: " + menuService); // pint null
}
}
靜態(tài)屬性(字段)注入
靜態(tài)屬性(字段)或方法是不會(huì)進(jìn)行依賴注入的。
@Service
public class UserService {
@Autowired
private static RoleService roleService;
public void printRole() {
System.out.println(roleService);
}
}
但是實(shí)際開(kāi)發(fā)中,我們可能會(huì)遇到此問(wèn)題。因此,有兩種方式解決此問(wèn)題:
構(gòu)造方法注入
@Service
public class UserService {
private static RoleService roleService;
// 解決靜態(tài)導(dǎo)入第一種方式:構(gòu)造函數(shù)注入
@Autowired
public UserService(RoleService roleService) {
UserService.roleService = roleService;
}
public void printRole() {
System.out.println(roleService);
}
}
Setter方法注入
@Service
public class UserService {
private static RoleService roleService;
// 解決靜態(tài)導(dǎo)入第二種方式:Setter方法注入
@Autowired
public void setRoleService(RoleService roleService) {
UserService.roleService = roleService;
}
public void printRole() {
System.out.println(roleService);
}
}
小結(jié)
綜上所述,@Autowired有三種注入方式,分別為:字段(屬性)注入,構(gòu)造函數(shù)注入和Setter方法注入。
另外,@Autowired參數(shù)注入,僅在單元測(cè)試才有意義;靜態(tài)字段(屬性)注入為空問(wèn)題,需要結(jié)合構(gòu)造函數(shù)或Setter方法注入。