先说结论

  • 如果只提供了一个无参的构造方法:返回 null
  • 如果只提供了一个有参的构造方法:返回 1
  • 如果提供了多个 @Autowired

Spring 在推断构造方法的时候,如果提供了多个合格的构造方法,会使用哪一个构造方法来创建实例呢?

  1. public class IndexService {
  2. public IndexService(){
  3. System.out.println("IndexService using default constructor");
  4. }
  5. public IndexService(UserService userService){
  6. System.out.println("IndexService using userService constructor");
  7. }
  8. public IndexService(UserService userService, OrderService orderService){
  9. System.out.println("IndexService using userService & orderService constructor");
  10. }
  11. }

答案是,使用默认的构造方法创建实例

如果在需要的构造方法上加上了注解 @Autowired 呢

  1. @Component
  2. public class IndexService {
  3. public IndexService(){
  4. System.out.println("IndexService using default constructor");
  5. }
  6. public IndexService(UserService userService){
  7. System.out.println("IndexService using userService constructor");
  8. }
  9. @Autowired
  10. public IndexService(UserService userService, OrderService orderService){
  11. System.out.println("IndexService using userService & orderService constructor");
  12. }
  13. }

答案是:很简单,既然你指定了需要注入的构造方法,我就使用你提供的构造方法

那么如果我想让 Spring 自动推断出最长参数的构造方法,除了使用 @Autowried 还有别的方法么?答案肯定是有的,那么我们就需要使用 BeanFactoryPostProcessor 了,利用他改变 AutowireMode 模型为 AUTOWIRE_CONSTRUCTOR,此时就能自动使用参数最长的构造方法了

  1. @Component
  2. public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
  3. @Override
  4. public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
  5. GenericBeanDefinition bd = (GenericBeanDefinition) beanFactory.getBeanDefinition("indexService");
  6. bd.setAutowireMode(GenericBeanDefinition.AUTOWIRE_CONSTRUCTOR);
  7. }
  8. }

Spring 是如果推断构造方法的

  1. Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
  2. if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
  3. mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
  4. // 再次进行推断,并确定使用哪一个构造方法,并注入
  5. return autowireConstructor(beanName, mbd, ctors, args);
  6. }

开始推断构造方法:处理实现了 SmartInstantiationAwareBeanPostProcessor 接口的后置处理器 AutowiredAnnotationBeanPostProcessor

1、提供了一个构造方法,是无参构造方法:
ctors == null

2、提供了一个构造方法,不是无参构造方法:
ctors = 1,会使用提供的构造方法,因为可以只能使用这个构造方法

3、提供了多个合格的构造方法,包括无参构造方法:
ctors == null,会调用无参构造方法,因为 spring 不知道应该利用那个构造方法装配

4、提供了多个合格的构造方法,不含无参构造方法,且都没有将其标明 @Autowired,且注入模式是 no:
ctors == null,然后抛出异常:No default constructor found

5、提供了多个合格的构造方法,不含无参构造方法,且都没有将其标明 @Autowired,且注入模式是 byConstructor:
ctors == null,找到参数值最长的合理的构造方法

6、提供了多个合格的构造方法,不含无参构造方法,且都将其标明 @Autowired(required=false):
ctors != null,找到参数值最长的合理的构造方法

7、提供了多个合格的构造方法,至少有一个标明了 @Autowired(required=false)
ctors != null,会继续推断使用哪一个构造方法,通常为第一个解析到的构造方法(这里会参数长度排序)

8、提供了多个合格的构造方法,至少有一个标明了 @Autowired(required=true) 和 @Autowired(required=false)
直接报异常:Invalid autowire-marked constructor

文字不写了,看注释…

  1. @Override
  2. @Nullable
  3. public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
  4. throws BeanCreationException {
  5. // Let's check for lookup methods here...
  6. // 是否检查过 lookup 方法
  7. if (!this.lookupMethodsChecked.contains(beanName)) {
  8. try {
  9. ReflectionUtils.doWithMethods(beanClass, method -> {
  10. Lookup lookup = method.getAnnotation(Lookup.class);
  11. if (lookup != null) {
  12. Assert.state(this.beanFactory != null, "No BeanFactory available");
  13. LookupOverride override = new LookupOverride(method, lookup.value());
  14. try {
  15. RootBeanDefinition mbd = (RootBeanDefinition)
  16. this.beanFactory.getMergedBeanDefinition(beanName);
  17. mbd.getMethodOverrides().addOverride(override);
  18. }
  19. catch (NoSuchBeanDefinitionException ex) {
  20. throw new BeanCreationException(beanName,
  21. "Cannot apply @Lookup to beans without corresponding bean definition");
  22. }
  23. }
  24. });
  25. }
  26. catch (IllegalStateException ex) {
  27. throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
  28. }
  29. this.lookupMethodsChecked.add(beanName);
  30. }
  31. // Quick check on the concurrent map first, with minimal locking.
  32. // ★ candidateConstructorsCache:存放已经被推断完成的类和该类被推断出来的构造方法的集合
  33. // 检查当前的类是否在 candidateConstructorsCache 中已经存在了已经推断过的构造方法,如果被推断过,就直接拿出来使用
  34. Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
  35. if (candidateConstructors == null) {
  36. // Fully synchronized resolution now...
  37. synchronized (this.candidateConstructorsCache) {
  38. candidateConstructors = this.candidateConstructorsCache.get(beanClass);
  39. if (candidateConstructors == null) {
  40. Constructor<?>[] rawCandidates;
  41. try {
  42. // 拿到所有的构造方法
  43. rawCandidates = beanClass.getDeclaredConstructors();
  44. }
  45. catch (Throwable ex) {
  46. throw new BeanCreationException(beanName,
  47. "Resolution of declared constructors on bean Class [" + beanClass.getName() +
  48. "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
  49. }
  50. // 存放合格的构造方法,但是合格,并不代表都可用
  51. List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
  52. // 必要的构造方法,比如在构造方法上加 @Autowired
  53. Constructor<?> requiredConstructor = null;
  54. // 默认无参构造方法
  55. Constructor<?> defaultConstructor = null;
  56. // 推断主要的构造方法委托给 Kotlin,如果对于 Java 类,永远返回 null
  57. Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
  58. // 定义一个变量记录非合成的构造方法
  59. int nonSyntheticConstructors = 0;
  60. for (Constructor<?> candidate : rawCandidates) {
  61. if (!candidate.isSynthetic()) {
  62. nonSyntheticConstructors++;
  63. }
  64. else if (primaryConstructor != null) {
  65. continue;
  66. }
  67. // 检查构造方法上有没有 @Autowired 注解,并拿出 注解上的 属性
  68. AnnotationAttributes ann = findAutowiredAnnotation(candidate);
  69. // 没有 @Autowired 注解的情况
  70. if (ann == null) {
  71. // 看看 beanClass 是否是 CGLIB 代理类,并且是否有父类
  72. Class<?> userClass = ClassUtils.getUserClass(beanClass);
  73. if (userClass != beanClass) {
  74. try {
  75. Constructor<?> superCtor =
  76. userClass.getDeclaredConstructor(candidate.getParameterTypes());
  77. ann = findAutowiredAnnotation(superCtor);
  78. }
  79. catch (NoSuchMethodException ex) {
  80. // Simply proceed, no equivalent superclass constructor found...
  81. }
  82. }
  83. }
  84. // 有 @Autowired 注解的情况
  85. if (ann != null) {
  86. // 有注解,并且 @Autowired(required=true),但是第一次肯定等于 null
  87. if (requiredConstructor != null) {
  88. throw new BeanCreationException(beanName,
  89. "Invalid autowire-marked constructor: " + candidate +
  90. ". Found constructor with 'required' Autowired annotation already: " +
  91. requiredConstructor);
  92. }
  93. // 推断注解上的值,也就是 required 的值
  94. boolean required = determineRequiredStatus(ann);
  95. if (required) {
  96. // 循环构造方法,如果发现多个 @Autowired 的构造方法,就会抛出异常
  97. if (!candidates.isEmpty()) {
  98. throw new BeanCreationException(beanName,
  99. "Invalid autowire-marked constructors: " + candidates +
  100. ". Found constructor with 'required' Autowired annotation: " +
  101. candidate);
  102. }
  103. // 给 requiredConstructor 赋值为 找到的构造方法
  104. requiredConstructor = candidate;
  105. }
  106. // 将构造方法放到 candidates 集合中
  107. candidates.add(candidate);
  108. }
  109. // 构造方法没有任何参数,说明是默认构造方法
  110. else if (candidate.getParameterCount() == 0) {
  111. defaultConstructor = candidate;
  112. }
  113. }
  114. if (!candidates.isEmpty()) {
  115. // Add default constructor to list of optional constructors, as fallback.
  116. if (requiredConstructor == null) {
  117. if (defaultConstructor != null) {
  118. candidates.add(defaultConstructor);
  119. }
  120. else if (candidates.size() == 1 && logger.isInfoEnabled()) {
  121. logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
  122. "': single autowire-marked constructor flagged as optional - " +
  123. "this constructor is effectively required since there is no " +
  124. "default constructor to fall back to: " + candidates.get(0));
  125. }
  126. }
  127. // 推断多个构造方法
  128. candidateConstructors = candidates.toArray(new Constructor<?>[0]);
  129. }
  130. // 只提供了一个构造方法,并且是含参的
  131. else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
  132. candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
  133. }
  134. // 不会执行:primaryConstructor != null 是与 kotlin 相关,
  135. else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
  136. defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
  137. candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
  138. }
  139. // 不会执行:primaryConstructor != null 是与 kotlin 相关
  140. else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
  141. candidateConstructors = new Constructor<?>[] {primaryConstructor};
  142. }
  143. // 其他的情况,返回一个空集合
  144. else {
  145. candidateConstructors = new Constructor<?>[0];
  146. }
  147. // 将推断出来的构造方法存起来
  148. this.candidateConstructorsCache.put(beanClass, candidateConstructors);
  149. }
  150. }
  151. }
  152. // 返回多个构造方法的情况是:有多个 @Autowired(required=false),才会成立
  153. return (candidateConstructors.length > 0 ? candidateConstructors : null);
  154. }