Spring依赖注入与默认构造器的优先级疑问:Car类将使用哪个Motor实例?
嘿,这个问题问到点子上了!我来给你理清楚Spring容器处理这个Car类实例化的逻辑,以及最终会用哪个Motor实例:
首先,先明确Spring的核心规则:当一个被Spring管理的类(比如你的Car加了@Component)存在多个构造器,并且其中至少一个构造器被@Autowired标记时,Spring会优先选择这个被标记的构造器来创建实例——前提是它所需的依赖能在容器中找到。
分两种情况具体分析:
情况1:
Motor是Spring容器中的Bean
如果你的Motor类也被Spring管理(比如加了@Component注解,或者通过@Bean方法注册到容器),那么Spring会直接调用带@Autowired的构造器public Car(Motor motor),把容器中的Motor实例注入进来。这时候Car里的motor属性就是容器中的那个实例,完全不会触发无参构造器里new Motor("created by Car")的逻辑。情况2:
Motor不是Spring容器中的Bean
因为你给构造器加的@Autowired默认是required=true(这是注解的默认属性),Spring会尝试寻找Motor类型的Bean,但找不到的话,启动时会直接抛出NoSuchBeanDefinitionException,容器初始化失败。
如果你把@Autowired改成@Autowired(required=false),那Spring会在找不到Motor依赖时, fallback到无参构造器,这时候Car里的motor就是你在无参构造器中手动new出来的那个实例。
额外补充个小知识点:
如果你的类有多个构造器,但没有任何一个被@Autowired标记,Spring 4.3+会优先选择无参构造器(如果存在);如果没有无参构造器,会自动选择参数最多的那个构造器(前提是所有参数都能在容器中找到)。但你的情况不符合这个场景,因为你已经给其中一个构造器加了@Autowired。
内容的提问来源于stack exchange,提问作者AntonBoarf

