Spring boot 在读卡器中获取JobParameters的值
在JobConfiguration类中获取JobParameter的值时遇到问题。 与文档中的解释一样,我使用:Spring boot 在读卡器中获取JobParameters的值,spring-boot,spring-batch,Spring Boot,Spring Batch,在JobConfiguration类中获取JobParameter的值时遇到问题。 与文档中的解释一样,我使用: @Value("#{jobParameters['xxxxxxxx']}") String xxxxxxx et 但是,我有以下错误: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationExcep
@Value("#{jobParameters['xxxxxxxx']}") String xxxxxxx
et
但是,我有以下错误:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [org.springframework.batch.core.Job]: Factory method 'PeopleJobConfiguration' threw exception;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.step1':
Scope 'step' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton;
nested exception is java.lang.IllegalStateException: No context holder available for step scope
我的错误是在我的步骤之前使用@StepScope。
这是我更正后的代码:
@SpringBootApplication
public class SpringBatchSimpleTestApplication {
private static final Logger log = LoggerFactory.getLogger(SpringBatchSimpleTestApplication.class);
public static void main(String[] args) throws Exception {
Resource[] resource = ctx.getResources("file:c:/tmp/person*.csv");
String filename;
for (int i = 0; i < resource.length; i++) {
filename = resource[i].getFile().getName();
Job job = ctx.getBean("PersonJobConfiguration", Job.class);
JobLauncher jobLauncher = ctx.getBean(JobLauncher.class);
JobParameters params = new JobParametersBuilder()
.addString("file123", filename)
.toJobParameters();
jobLauncher.run(job, params);
}
}
}
@springboot应用程序
公共类SpringBatchSimpleTestApplication{
私有静态最终记录器log=LoggerFactory.getLogger(SpringBatchSimpleTestApplication.class);
公共静态void main(字符串[]args)引发异常{
Resource[]Resource=ctx.getResources(“文件:c:/tmp/person*.csv”);
字符串文件名;
for(int i=0;i
===============================================================
@Configuration
@EnableBatchProcessing
public class PeopleJobConfiguration {
private static final Logger log = LoggerFactory.getLogger(PeopleJobConfiguration.class);
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@StepScope
@Bean
public FlatFileItemReader<Person> reader1(@Value("#{jobParameters['file123']}") String file123) {
log.debug("A-file123: "+file123);
return new FlatFileItemReaderBuilder<Person>()
.name("personItemReader")
.resource(new ClassPathResource(file123))
.lineTokenizer(new FixedLengthTokenizer() {{ setNames("firstName", "lastName", "age'"); setColumns(new Range(1,4), new Range(5,6),new Range(7)); }})
.fieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{ setTargetType(Person.class); }})
.build()
;
}
@Bean
public PersonItemProcessor processor() {
return new PersonItemProcessor();
}
@Bean
public JdbcBatchItemWriter<Person> writer1(DataSource dataSource) {
JdbcBatchItemWriter<Person> jdbcBatchItemWriter = new JdbcBatchItemWriter<>();
jdbcBatchItemWriter.setAssertUpdates(true);
jdbcBatchItemWriter.setDataSource(dataSource);
jdbcBatchItemWriter.setSql("INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)");
jdbcBatchItemWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<Person>());
return jdbcBatchItemWriter;
}
@Bean
public JdbcBatchItemWriter<Person> writer2(DataSource dataSource) {
return new JdbcBatchItemWriterBuilder<Person>()
.itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
.sql("INSERT INTO people2 (first_name, last_name, age) VALUES (:firstName, :lastName, :age)")
.dataSource(dataSource)
.build();
}
@Bean
public CompositeItemWriter compositeItemWriter(JdbcBatchItemWriter<Person> writer1,JdbcBatchItemWriter<Person> writer2) {
CompositeItemWriter itemWriter = new CompositeItemWriter();
itemWriter.setDelegates(Arrays.asList(writer1, writer2));
return itemWriter;
}
@Bean
public Job PeopleJobConfiguration(JobEndListener listener, Step step1) {
return jobBuilderFactory.get("PeopleJobConfiguration")
.listener(listener)
.flow(step1)
.end()
.build();
}
@Bean
public Step step1(JdbcBatchItemWriter<Person> writer1,JdbcBatchItemWriter<Person> writer2, FlatFileItemReader<Person> reader1) {
log.debug("B-file123: "+file123);
return stepBuilderFactory.get("step1")
.<Person,Person> chunk(3)
.reader(reader1)
.writer(compositeItemWriter(writer1, writer2))
.build();
}
}
@配置
@启用批处理
公共类PeopleJobConfiguration{
私有静态最终记录器log=LoggerFactory.getLogger(PeopleJobConfiguration.class);
@自动连线
公共建筑商建筑商工厂;
@自动连线
公共StepBuilderFactory StepBuilderFactory;
@步进镜
@豆子
公共FlatFileItemReader读取器1(@Value(“#{jobParameters['file123']}”)字符串file123){
log.debug(“A-file123:+file123”);
返回新的FlatFileItemReaderBuilder()
.名称(“personItemReader”)
.resource(新类路径资源(文件123))
.lineTokenizer(新的FixedLengthTokenizer(){{setNames(“firstName”、“lastName”、“age”));setColumns(新范围(1,4)、新范围(5,6)、新范围(7));}
.fieldSetMapper(新的BeanWrapperFieldSetMapper(){{setTargetType(Person.class);}})
.build()
;
}
@豆子
公共PersonItemProcessor处理器(){
返回新的PersonItemProcessor();
}
@豆子
公共JdbcBatchItemWriter写入程序1(数据源数据源){
JdbcBatchItemWriter JdbcBatchItemWriter=新的JdbcBatchItemWriter();
jdbcBatchItemWriter.setAssertUpdate(true);
setDataSource(dataSource);
jdbccbatchitemwriter.setSql(“插入到人(名字,姓氏)值(:firstName,:lastName)”);
jdbcBatchItemWriter.setItemSqlParameterSourceProvider(新的BeanPropertyItemSqlParameterSourceProvider());
返回jdbcBatchItemWriter;
}
@豆子
公共JdbcBatchItemWriter编写器2(数据源数据源){
返回新的JdbcBatchItemWriterBuilder()
.itemSqlParameterSourceProvider(新的BeanPropertyItemSqlParameterSourceProvider())
.sql(“插入people2(名字、姓氏、年龄)值(:firstName,:lastName,:age)”)
.dataSource(数据源)
.build();
}
@豆子
公共CompositeItemWriter CompositeItemWriter(JdbcBatchItemWriter编写器1、JdbcBatchItemWriter编写器2){
CompositeItemWriter itemWriter=新的CompositeItemWriter();
setDelegates(Arrays.asList(writer1,writer2));
返回项目编写器;
}
@豆子
公共作业人员JobConfiguration(JobEndListener侦听器,步骤1){
返回jobBuilderFactory.get(“PeopleJobConfiguration”)
.listener(侦听器)
.流程(步骤1)
(完)
.build();
}
@豆子
公共步骤步骤1(JdbcBatchItemWriter写入程序1、JdbcBatchItemWriter写入程序2、FlatFileItemReader读取程序1){
log.debug(“B-file123:+file123”);
返回stepBuilderFactory.get(“step1”)
.chunk(3)
.读卡器(读卡器1)
.writer(compositeItemWriter(writer1,writer2))
.build();
}
}
在这里定义一个范围为步骤的bean是没有意义的:
@StepScope
@Bean
public Step step1(JdbcBatchItemWriter<Person> writer1,JdbcBatchItemWriter<Person> writer2, @Value("#{jobParameters['file123']}") String file123) {
log.debug("B-file123: "+file123);
return stepBuilderFactory.get("step1")
.<Person,Person> chunk(3)
.reader(reader1(file123))
.writer(compositeItemWriter(writer1, writer2))
.build();
}
好的,我删除了“step1”bean之前的@StepScope
,并添加了类似step1的flatfileitemreader1
参数。没有错误,但reader1中的“file123”始终为空。PeopleJobConfiguration的作业定义中没有要添加的内容?不要删除reader bean上的@StepScope
,只删除step bean上的。新问题可能是因为您在.resource(新类路径资源(“file123”)
中传递字符串literal“file123”
,而不是实际参数:这应该是.resource(新类路径资源(file123))
。请将问题更新为您每次所做的最新更改,以便能够有效地帮助您。多亏了您,我理解了我的错误。非常感谢你。
@StepScope
@Bean
public Step step1(JdbcBatchItemWriter<Person> writer1,JdbcBatchItemWriter<Person> writer2, @Value("#{jobParameters['file123']}") String file123) {
log.debug("B-file123: "+file123);
return stepBuilderFactory.get("step1")
.<Person,Person> chunk(3)
.reader(reader1(file123))
.writer(compositeItemWriter(writer1, writer2))
.build();
}
@Bean
public Step step1(JdbcBatchItemWriter<Person> writer1,JdbcBatchItemWriter<Person> writer2, FlatFileItemReader<Person> reader) {
log.debug("B-file123: "+file123);
return stepBuilderFactory.get("step1")
.<Person,Person> chunk(3)
.reader(reader)
.writer(compositeItemWriter(writer1, writer2))
.build();
}