使用 Spring Boot 动态实例化 class 的依赖注入
Dependency Injection with dynamically instanciated class with Spring Boot
我正在尝试开发一个 spring-boot 应用程序,它为用户提供了创建和调用一些简单工作流的可能性。
工作流的步骤已经写好(它们都扩展相同 class),并且当用户创建工作流时,he/she 只需选择他想要包含在他的工作流中的步骤它。步骤和工作流程保存在数据库中。
当用户调用工作流时,我的问题就来了:我想使用 class 加载程序动态实例化每个步骤,但要使用 spring!
注入的依赖项
这是一个插件的例子:
public class HelloWorldStepPlugin extends StepPlugin {
private static final Logger LOG = LogManager.getLogger();
@Autowired
private HelloWorldRepository repository;
public HelloWorldStepPlugin() {
super(HelloWorldStepPlugin.class.getSimpleName());
}
@Override
public void process() {
LOG.info("Hello world!");
this.repository.findAll(); // <= throw a NullPointerException because this.repository is null
}
}
以下是我执行工作流程的方式(在另一个 class 中):
ClassLoader cl = getClass().getClassLoader();
for (Step s : workflow.getSteps()) {
StepPlugin sp = (StepPlugin) cl.loadClass(STEP_PLUGIN_PACKAGE + s.getPlugin()).newInstance();
sp.process();
}
如何让 Spring 注入我的 HelloWorldRepository?
有没有更好的方法来实现我的意图?
我建议您将步骤声明为原型 bean。不要在数据库中保存 class 个名称,而是保存 bean 名称。然后从 spring 上下文中获取步骤和插件(即使用 getBean())。
我正在尝试开发一个 spring-boot 应用程序,它为用户提供了创建和调用一些简单工作流的可能性。
工作流的步骤已经写好(它们都扩展相同 class),并且当用户创建工作流时,he/she 只需选择他想要包含在他的工作流中的步骤它。步骤和工作流程保存在数据库中。
当用户调用工作流时,我的问题就来了:我想使用 class 加载程序动态实例化每个步骤,但要使用 spring!
注入的依赖项这是一个插件的例子:
public class HelloWorldStepPlugin extends StepPlugin {
private static final Logger LOG = LogManager.getLogger();
@Autowired
private HelloWorldRepository repository;
public HelloWorldStepPlugin() {
super(HelloWorldStepPlugin.class.getSimpleName());
}
@Override
public void process() {
LOG.info("Hello world!");
this.repository.findAll(); // <= throw a NullPointerException because this.repository is null
}
}
以下是我执行工作流程的方式(在另一个 class 中):
ClassLoader cl = getClass().getClassLoader();
for (Step s : workflow.getSteps()) {
StepPlugin sp = (StepPlugin) cl.loadClass(STEP_PLUGIN_PACKAGE + s.getPlugin()).newInstance();
sp.process();
}
如何让 Spring 注入我的 HelloWorldRepository? 有没有更好的方法来实现我的意图?
我建议您将步骤声明为原型 bean。不要在数据库中保存 class 个名称,而是保存 bean 名称。然后从 spring 上下文中获取步骤和插件(即使用 getBean())。