Я пытаюсь разработать приложение с пружинной загрузкой, которое дает возможность пользователю создавать и вызывать некоторые простые рабочие процессы.Depency Injection с динамическим instanciated классом с Spring Boot
Шаги рабочих процессов уже написаны (все они расширяют один и тот же класс), и когда пользователь создает рабочий процесс, он просто выбирает, какие шаги он хочет включить в него. Этапы и рабочие процессы сохраняются в базе данных.
Моя проблема возникает, когда пользователь вызывает рабочий процесс: я хочу динамически запускать каждый шаг с помощью загрузчика классов, но с зависимостями, введенными весной!
Вот пример плагина:
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
}
}
Вот как я исполняю Workflow (в другом классе):
ClassLoader cl = getClass().getClassLoader();
for (Step s : workflow.getSteps()) {
StepPlugin sp = (StepPlugin) cl.loadClass(STEP_PLUGIN_PACKAGE + s.getPlugin()).newInstance();
sp.process();
}
Как я могу сделать, чтобы мне HelloWorldRepository впрыскивается по весне? Есть ли гораздо лучший подход к тому, что я намерен?
Спасибо за ваш ответ. Как я могу объявить свой класс в качестве прототипа? – Eric
вы можете использовать аннотацию @Scope («prototype»). –
... и если вы добавите @ org.springframework.context.annotation.Lazy аннотации к классу, то ваш класс будет создан лениво. –