排序答案是肯定的。这是比 Spring Batch 更通用的 spring/设计模式问题评估器。
Spring Batch 的棘手部分是 bean 创建的配置和理解范围。
让我们假设你所有的 Strategies 都实现了如下所示的 Strategy 接口:
interface Strategy {
int execute(int a, int b);
};
每个策略都应该实现策略并使用@Component 注解来允许自动发现新的策略。确保所有新策略都放在正确的包下,以便组件扫描可以找到它们。
例如:
@Component
public class StrategyA implements Strategy {
@Override
public int execute(int a, int b) {
return a+b;
}
}
以上是单例,将在应用程序上下文初始化时创建。
这个阶段使用 @Value("#{jobParameters['strategy']}") 为时尚早,因为 JobParameter 尚未创建。
所以我建议使用一个定位器 bean,稍后在创建 myTasklet 时使用它(Step Scope)。
StrategyLocator 类:
public class StrategyLocator {
private Map<String, ? extends Strategy> strategyMap;
public Strategy lookup(String strategy) {
return strategyMap.get(strategy);
}
public void setStrategyMap(Map<String, ? extends Strategy> strategyMap) {
this.strategyMap = strategyMap;
}
}
配置如下:
@Bean
@StepScope
public MyTaskelt myTasklet () {
MyTaskelt myTasklet = new MyTaskelt();
//set the strategyLocator
myTasklet.setStrategyLocator(strategyLocator());
return myTasklet;
}
@Bean
protected StrategyLocator strategyLocator(){
return = new StrategyLocator();
}
要初始化 StrategyLocator,我们需要确保所有策略都已创建。所以最好的方法是在 ContextRefreshedEvent 事件上使用 ApplicationListener (在这个例子中警告策略名称以小写字母开头,改变这个很容易......)。
@Component
public class PlugableStrategyMapper implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private StrategyLocator strategyLocator;
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
ApplicationContext applicationContext = contextRefreshedEvent.getApplicationContext();
Map<String, Strategy> beansOfTypeStrategy = applicationContext.getBeansOfType(Strategy.class);
strategyLocator.setStrategyMap(beansOfTypeStrategy);
}
}
tasklet 将保存一个 String 类型的字段,该字段将使用 @Value 注入 Strategy enum String ,并将使用“前一步”侦听器使用定位器解析。
public class MyTaskelt implements Tasklet,StepExecutionListener {
@Value("#{jobParameters['strategy']}")
private String strategyName;
private Strategy strategy;
private StrategyLocator strategyLocator;
@BeforeStep
public void beforeStep(StepExecution stepExecution) {
strategy = strategyLocator.lookup(strategyName);
}
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
int executeStrategyResult = strategy.execute(1, 2);
}
public void setStrategyLocator(StrategyLocator strategyLocator) {
this.strategyLocator = strategyLocator;
}
}
要将侦听器附加到 taskelt,您需要在步骤配置中进行设置:
@Bean
protected Step myTaskletstep() throws MalformedURLException {
return steps.get("myTaskletstep")
.transactionManager(transactionManager())
.tasklet(deleteFileTaskelt())
.listener(deleteFileTaskelt())
.build();
}