做一个单纯的程序汪,分享干货,聊聊人生。
微信公众号:后端架构进阶
关注我发现更多的干货,微服务、Spring源码、JVM、SpringCloud Alibaba、K8S等。
前面讨论了Bean的获取和创建的方式。今天继续讨论我们的Spring,前两篇没看的可以去看看。
每天五分钟,学透Spring《一、Spring中是如何获取Bean》
一、什么是构造方法推断?
我们都知道,Spring在基于某个类生成Bean的过程中,需要利用该类的构造方法来实例化得到一个对象,但是如果一个类存在多个构造方法,Spring会使用哪个呢?最终选定使用哪个构造方法的过程就是构造方法推断。
二、推断逻辑
- 如果一个类只存在一个构造方法,那么无论这个构造方法是无参还是有参Spring都会用这个构造方法。
/**
* 构造推断
*
* @author AerCool Yang
* @date 2021-12-11 14:09:56
*/
@Component
public class UserService {
public UserService() {
System.out.println("我是无参构造方法!");
}
public static void main(String[] args) {
try (AnnotationConfigApplicationContext con =
new AnnotationConfigApplicationContext(Config.class)) {
Object userService = con.getBean("userService");
System.out.println(userService);
}
}
}
我们可以看到输出了如下内容。
我是无参构造方法!
com.aercool.construct.UserService@54bff557
如果是有参呢?
/**
* 有参构造推荐
*
* @author AerCool Yang
* @date 2021-12-11 14:09:56
*/
@Component
public class UserService {
public UserService(String name) {
System.out.println("我是有参构造方法:" + name);
}
public static void main(String[] args) {
try (AnnotationConfigApplicationContext con =
new AnnotationConfigApplicationContext(Config.class)) {
Object userService = con.getBean("userService");
System.out.println(userService);
}
}
}
可以看到报错了,因为去创建有参的Bean的时候,没有传入参数。
但是,如果上面既有有参又有有参,那么会使用无参的。无参的就是默认构造方法,所以为什么说如果我们创建了有参构造方法,必须把无参的构造方法也自己创建了。
但是如果我有参和无参都有,我要用有参构造方法要怎么使用呢?答案是:在要用的方法上加上@Autowired
/**
* 有参和无参同时存在
*
* @author AerCool Yang
* @date 2021-12-11 14:09:56
*/
@Component
public class UserService {
public UserService() {
System.out.println("我是无参构造方法");
}
@Autowired
public UserService(String name) {
System.out.println("我是有参构造方法:" + name);
}
public static void main(String[] args) {
try (AnnotationConfigApplicationContext con =
new AnnotationConfigApplicationContext(Config.class)) {
Object userService = con.getBean("userService");
System.out.println(userService);
}
}
}
这个时候就会加载有参的构造方法了。
三、有参构造参数如何得来?
从上面我们可以看到,Spring会根据入参的类型和入参的名字去Spring中找Bean对象,如果找到,就会当作初始化该类的参数。如果没找到就报错了。我们来演示下可以找到的情况。
/**
* 构造方法推断
*
* @author AerCool Yang
* @date 2021-12-11 14:09:56
*/
@Component
public class UserService {
public UserService() {
System.out.println("我是无参构造方法");
}
@Autowired
public UserService(OrderService orderService) {
System.out.println("我是UserService的有参构造方法:" + orderService);
}
public static void main(String[] args) {
try (AnnotationConfigApplicationContext con =
new AnnotationConfigApplicationContext(Config.class)) {
Object userService = con.getBean("userService");
System.out.println(userService);
}
}
}
上面的方法执行的结果是这样的:
OrderService的无参构造初始化了...
我是UserService的有参构造方法:com.aercool.construct.OrderService@2034b64c
com.aercool.construct.UserService@2b40ff9c
所以综上来说:
- 当去找
userService的时候,第一次会去初始化userService; - 初始化userService的时候,发现是用的有参构造,然后去找orderService,没有就去初始化;
- 然后把orderService给初始化了;
- 最终日志打印就是上面的效果了。
四、小结
作为Java开发,其实我们工作中时时刻刻都在使用我们的Spring,这些现象其实早就遇到过,只是可能没注意罢了。
好了,今天的文章就分享这么多。后面会分享事务、AOP相关内容,敬请期待!
总结
以上就是今日内容的总结和分享,感谢各位大佬的 点赞、关注和 收藏 !
微信公众号:后端架构进阶
更多文章正在赶来,喜欢记得给我点个 👍 ,感谢支持!
公众号文章同步更新!关注我,不迷路!