1

Я пытаюсь разработать приложение с пружинной загрузкой, которое дает возможность пользователю создавать и вызывать некоторые простые рабочие процессы.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 впрыскивается по весне? Есть ли гораздо лучший подход к тому, что я намерен?

ответ

2

Предлагаю вам указать свои шаги в качестве прототипов. Вместо сохранения имен классов в базе данных сохраните имена бинов. Затем получите шаги и плагины из контекста весны (т. Е. С помощью getBean()).

+0

Спасибо за ваш ответ. Как я могу объявить свой класс в качестве прототипа? – Eric

+2

вы можете использовать аннотацию @Scope («prototype»). –

+0

... и если вы добавите @ org.springframework.context.annotation.Lazy аннотации к классу, то ваш класс будет создан лениво. –