使用运行时定义的配置按需实例化 Bean

Instantiate Bean on Demand With Runtime-Defined Configuration

在我的应用程序中,我想根据需要实例化一个 class 并将一些运行时参数传递给它,并让 Spring 自动满足任何 @Autowired 依赖项。比如我想按需实例化的class:

@Service
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class FileProcess implements Runnable
{
    @Autowired
    private MyDAO myDAO;

    private String configOne;

    private String configTwo;

    @Override
    public void run()
    {
    }
}

对象 myDAO 已经存在于 ApplicationContext 中,我希望 Spring 为我完成这个依赖。事实上,这个 class 的任何实例都不应该真正知道 FileProcess 的内部结构,只是它需要配置参数 configOneconfigTwo

为了获取 FileProcess 的实例,我使用了 ApplicationContextgetBean() 方法,但我无法仅传入配置参数:

final FileProcess fileProcess = this.applicationContext.getBean(FileProcess.class, configOne, configTwo)

这会导致错误:

Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities

我发现无论我向 FileProcess 添加什么构造函数,我都会得到同样的错误。我只想传递配置参数而不是,在这种情况下不是 MyDAO 的实例。同样,必须传入 MyDAO 的实例意味着调用者必须了解 FileProcess 的内部结构,并且通常必须了解此类 bean 的范围。

有没有一种方法可以实现这一点而不必诉诸 @Configuration class 和 @Bean 注释方法?

我认为你最好使用工厂 bean,比如

@Bean
BiFunction<String, String, FileProcess> createFileProcess(MyDAO dao) {
    return (c1, c2) -> {
        FileProcess result = new FileProcess(dao) ;
        result.setConfig1(c1);
        result.setConfig2(c2);
        return result;
   };
}

这在配置 class 中,您可以自动装配它以使用您的配置值创建进程对象。

@Autowired
BiFunction<String, String, FileProcess> processFactory;
... 
FileProcess p = processFactory.apply("val1", "val2");