Spring同一接口多prototype Bean工厂自定义传参构造匹配异常问题
问题根因
ApplicationContext.getBean(Class<T> type, Object... args) 重载方法的默认逻辑为:当你显式传入构造参数时,Spring会直接用你传入的所有参数匹配构造器,不会再自动注入构造函数中的Bean依赖。你仅传入String参数时,无法匹配需要CopyService+String的构造器,因此抛出找不到匹配构造函数的异常。
符合Spring规范的实现方案
方案1:使用@Bean工厂方法声明原型Bean(优先推荐)
代码改动最小,可保留所有字段的final修饰符,不破坏原有类的不可变设计。
- 新增配置类,声明每个Command的原型Bean工厂方法:
@Configuration public class CommandConfig { // Spring创建Bean时会自动注入CopyService,你传入的自定义参数会作为第二个参数接收 @Bean @Scope("prototype") public CopyCommand copyCommand(CopyService copyService, String content) { return new CopyCommand(copyService, content); } @Bean @Scope("prototype") public PasteCommand pasteCommand(PasteService pasteService) { return new PasteCommand(pasteService); } }
- 原有Command实现类、工厂类代码无需修改,直接调用
factory.createCommand(CopyCommand.class, "some text")即可正常运行。
方案2:拆分构造注入与动态参数赋值
无需额外维护配置类,将动态参数从构造函数中移除,改用setter赋值。
- 修改CopyCommand实现:
@Component @Scope("prototype") @RequiredArgsConstructor public class CopyCommand implements Command { private final CopyService copyService; // 依然由Spring构造注入 private String content; // 动态参数改用setter赋值 @Override public String getAction() { return "COPY";} public void setContent(String content) { this.content = content; } }
- 修改工厂类的
createCommand方法:
public Command createCommand(Class<? extends Command> clazz, Object... args) { Command command = context.getBean(clazz); // 根据Bean类型匹配赋值动态参数 if (clazz == CopyCommand.class && args.length > 0) { ((CopyCommand) command).setContent((String) args[0]); } return command; }
内容的提问来源于stack exchange,提问作者michelson
相关产品推荐
相关产品推荐

