Spring推断构造方法

89 阅读2分钟

我们知道在Spring框架中,我们要得到一个对象,就需要进行实例化(spring生命周期的一个环节),而实例化就需要用到构造方法

先从3个简单的示例说起

示例1:

	
@Component
public class OrderService {
	public OrderService(UserService userService) {
		System.out.println("test1");
	}
	public OrderService(UserService userService, UserService userService1) {
		System.out.println("test2");
	}
	public OrderService() {
		System.out.println("test3");
	}
}

示例2:

	
@Component
public class OrderService {

	@Autowired
	public OrderService(UserService userService) {
		System.out.println("test1");
	}

	public OrderService(UserService userService, UserService userService1) {
		System.out.println("test2");
	}

	public OrderService() {
		System.out.println("test3");

	}
}

示例3:

	
@Component
public class OrderService {

	@Autowired
	public OrderService(UserService userService) {
		System.out.println("test1");
	}
	@Autowired(required = false)
	public OrderService(UserService userService, UserService userService1) {
		System.out.println("test2");
	}

	public OrderService() {
		System.out.println("test3");

	}
}

大家先想一下这3个示例最后的结论是什么再往下面看,效果会好一点,【答案我们放在最后】

关键源码

关键的2个方法: org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance

determineCandidateConstructors(Class<?> beanClass, String beanName)

这个方法的内容有点长,我会截取一些关键的代码说一下:

上面的1这个地方的代码可以暂时先不看,直接看2, 2这块的逻辑大概就是:

  • 先从缓存中看是否有候选的构造方法,如果有的话直接返回;
  • 如果缓存中没有候选的构造方法,通过反射拿出这个类的所有构造方法。如果还没构造方法则报错。

我们继续往下走,[见下图]

上面的这个地方第1个地方是存放添加注解@Autowired的构造方法的list,2这个地方其实就是拿出所有的构造方法让后进行各种判断(后面再讲)

3这个地方其实就是对1的这个list进行处理返回。

这个地方的细节还是蛮多的,我就不一一截图了,大家可以参考我在github上的代码: Spring带有源码注释的源代码

结论

实例答案
  • 示例1:test3
  • 示例2:test1
  • 示例3:报异常

原文链接