当多个构造函数具有@Autowired

时间:2019-07-08 00:03:17

标签: spring

Spring文档说:

  

每个类只能将一个带注释的构造函数标记为必需,但可以注释多个非必需的构造函数。在那种情况下,每个候选对象都被考虑在内,Spring使用最贪婪的构造函数,可以满足其依存关系-即,参数数量最多的构造函数。构造函数解析算法与带有重载构造函数的非注释类的算法相同,只是将候选对象缩小为带注释的构造函数。

我对其进行了测试,并且在我有另一个用@Autowired标记的构造函数时出现错误

package com.example.demo.constructorinjection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class ConstructorInjectComponent {   

private InjectionServiceOne injectionServiceOne;

private InjectionServiceTwo injectionServiceTwo;

@Autowired(required = true)
public constructorInjectComponent(InjectionServiceOne injectionServiceOne,
        InjectionServiceTwo injectionServiceTwo) {
    this.injectionServiceOne = injectionServiceOne;
    this.injectionServiceTwo = injectionServiceTwo;
}

@Autowired(required = false)
public constructorInjectComponent(InjectionServiceTwo injectionServiceTwo) {
    this.injectionServiceTwo = injectionServiceTwo;
}

@Autowired(required = false)
public constructorInjectComponent(InjectionServiceOne injectionServiceOne) {
    this.injectionServiceOne = injectionServiceOne;
}

@Scheduled(fixedRate=1000L)
public void allFieldsConstructorInjectionTest() {
    System.err.println("constructorInjection " + injectionServiceOne.method() + " " + injectionServiceTwo.method());
}
}

错误:

  

org.springframework.beans.factory.BeanCreationException:创建名称为'constructorInjectComponent'的bean时出错:无效的自动接线标记的构造函数:public com.example.demo.constructorinjection.constructorInjectComponent(com.example.demo.constructorinjection.InjectionServiceOne)。已找到具有“必需”自动装配注释的构造函数:public com.example.demo.constructorinjection.constructorInjectComponent(com.example.demo.constructorinjection.InjectionServiceOne,com.example.demo.constructorinjection.InjectionServiceTwo)       在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:314)〜[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]中       在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineConstructorsFromBeanPostProcessors(AbstractAutowireCapableBeanFactory.java:1269)〜[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]

问题:

为什么不能有多个标记为@Autowired的构造函数? Spring文档明确指出,我可以有多个标记为@Autowired的构造函数。

2 个答案:

答案 0 :(得分:2)

@AutowiredAutowiredAnnotationBeanPostProcessor处理,它的javadoc对此行为有更好的描述:

  

任何给定的bean类中只有一个构造函数(最大)可以声明此   注释,其中“ required”参数设置为true,表示   用作Spring bean时自动装配的构造函数。

此语句讨论'required' = true时的情况。

因此,如果'required' = true,则只有一个构造函数(最大)可以声明@Autowired

  

如果多个不需要的构造函数声明注释,则它们   将被视为自动装配的候选人。构造函数   通过匹配可以满足的最大数量的依赖关系   将选择Spring容器中的bean。

此语句暗含另一种情况(即'required' = false)。

因此,如果'required' = false允许有多个构造函数。


您可以在此for-loop的源代码中看到此检查逻辑,这些代码编写得很好,很容易理解。

答案 1 :(得分:1)

我做了一些测试,这就是我发现的东西。

只能用@Autowired标记一个构造函数(默认情况下required = true)。就是这样。不管require的值是多少,都不能用@Autowired标记其他构造函数。但是可以用@Autowired标记多个构造函数,但是它们都必须具有required = false。

请在我提出问题的地方page进行检查。我在page提出了改善文档的要求。