Spring在基于某个类生成Bean的过程中,需要通过构造方法来实例化对象,但是如果一个类存在多个构造方法时,Spring会使用哪一个?
在回答这个问题之前,先看几个例子:
例子一
配置类
package mytest.spring;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@ComponentScan("mytest.spring")
@Configuration
public class AppConfig {
}
用户服务
package mytest.spring;
import org.springframework.stereotype.Component;
@Component
public class UserService {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
定单服务,无参构造
package mytest.spring;
import org.springframework.stereotype.Component;
@Component
public class OrderService {
private UserService userService;
public void showResult() {
if (userService == null) {
System.out.println("用户服务未注入");
} else {
System.out.println("用户服务已注入");
}
}
}
//main方法测试
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
OrderService orderService = context.getBean("orderService", OrderService.class);
orderService.showResult();
}
输出结果为:“用户服务未注入”。
例子二
订单服务,一个有参构造
@Component
public class OrderService {
private UserService userService;
public OrderService(UserService userService) {
this.userService = userService;
}
public void showResult() {
if (userService == null) {
System.out.println("用户服务未注入");
} else {
System.out.println("用户服务已注入");
}
}
}
输出结果为:“用户服务已注入”。
例子三
订单服务,两个有参+无参构造
@Component
public class OrderService {
private UserService userService;
public OrderService() {
}
public OrderService(UserService userService) {
this.userService = userService;
}
public OrderService(UserService userService, UserService userService1) {
this.userService = userService;
}
public void showResult() {
if (userService == null) {
System.out.println("用户服务未注入");
} else {
System.out.println("用户服务已注入");
}
}
}
输出结果为:“用户服务未注入”。此时走的是无参构造。
例子四
订单服务,两个有参构造
@Component
public class OrderService {
private UserService userService;
public OrderService(UserService userService) {
this.userService = userService;
}
public OrderService(UserService userService, UserService userService1) {
this.userService = userService;
}
public void showResult() {
if (userService == null) {
System.out.println("用户服务未注入");
} else {
System.out.println("用户服务已注入");
}
}
}
输出结果:报错 No default constructor found
例子五
订单服务,两个有参构造+@Autowired
@Component
public class OrderService {
private UserService userService;
public OrderService(UserService userService) {
this.userService = userService;
System.out.println("2");
}
@Autowired
public OrderService(UserService userService, UserService userService1) {
this.userService = userService;
System.out.println("3");
}
public void showResult() {
if (userService == null) {
System.out.println("用户服务未注入");
} else {
System.out.println("用户服务已注入");
}
}
}
输出结果为:
“3”
“用户服务已注入”
总结:Spring推断构造逻辑如下
- 如果一个类只有一个构造方法,那没的选择,只能用这个构造方法
- 如果一个类有多个构造方法,首先会判断是否有@Autowired指定构造方法,再看是否有无参构造方法。如果都没有就会报错 No default constructor found