Java SpringBatch的Step块中的泛型方法
我实际上在使用SpringBatch,我一直在问自己一些关于泛型方法的问题。考虑到以下代码:Java SpringBatch的Step块中的泛型方法,java,generics,syntax,spring-batch,Java,Generics,Syntax,Spring Batch,我实际上在使用SpringBatch,我一直在问自己一些关于泛型方法的问题。考虑到以下代码: public <I, O> SimpleStepBuilder<I, O> chunk(int chunkSize) { return new SimpleStepBuilder<I, O>(this).chunk(chunkSize); } 我想这样定义上面定义的步骤: @Bean public Step step(final AccountReader
public <I, O> SimpleStepBuilder<I, O> chunk(int chunkSize) {
return new SimpleStepBuilder<I, O>(this).chunk(chunkSize);
}
我想这样定义上面定义的步骤:
@Bean
public Step step(final AccountReader accountReader, final AccountProcessor accountProcessor) {
return stepBuilderFactory.get("step")
.<COR_ACC_ACCOUNT, Account>chunk(10)
.reader(accountReader)
.processor(accountProcessor)
.writer(new JsonWriter<>())
.build();
}
@Bean
public Step step() {
return stepBuilderFactory.get("step")
.<COR_ACC_ACCOUNT, Account>chunk(10)
.reader(<COR_ACC_ACCOUNT>itemDictionary.getReader(AccountReader.class))
.processor(accountProcessor)
.writer(new JsonWriter<>())
.build();
}
itemDictionary基本上是一个包含Spring上下文中所有ItemReader实现的映射
此调用itemDictionary.getReaderAccountReader.class被编译器拒绝,因为它是表达式的非法开始
我错过什么了吗
仍然可以使用ItemDictionnary保留类型安全检查吗?是的,这种语法在java中实际上是错误的 您不能在这里保留类型安全性,因为当您将实现存储到私有最终映射项阅读器时,已经失去了类型安全性 我建议最简单的解决方案是进行类型转换:
(ItemReader<COR_ACC_ACCOUNT>) itemDictionary.getReader(AccountReader.class)
根据.chunk10,要读取的项目类型是COR_ACC_ACCOUNT,因此AccountReader应该返回这种类型的项目,在这种情况下,您不需要在此处进行转换:
.readeritemDictionary.getReaderAccountReader.class
我尝试了您的示例,但没有编译错误:
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableBatchProcessing
public class MyJob {
@Autowired
private JobBuilderFactory jobs;
@Autowired
private StepBuilderFactory steps;
@Bean
public ItemDictionary itemDictionary() {
return new ItemDictionary(Arrays.asList(new FooReader()));
}
@Bean
public ItemWriter<Bar> itemWriter() {
return null;
}
@Bean
public Step step() {
return steps.get("step")
.<Foo, Bar>chunk(5)
.reader(itemDictionary().getReader(Foo.class))
.writer(itemWriter())
.build();
}
@Bean
public Job job() {
return jobs.get("job")
.start(step())
.build();
}
public class ItemDictionary {
private Map<Class, ItemReader> itemReaders;
public ItemDictionary(final List<ItemReader> readers) {
itemReaders = readers.stream().collect(Collectors.toMap(
ItemReader::getClass,
Function.identity()
));
}
public <I> ItemReader<I> getReader(final Class clazz) {
return itemReaders.get(clazz);
}
}
class Foo { }
class Bar { }
class FooReader implements ItemReader<Foo> {
@Override
public Foo read() {
return null;
}
}
}
希望这能有所帮助。我承认,这个COR_ACC_账户只是一个名字古怪的POJO。它保存来自数据库的数据,仅此而已。没有涉及泛型类型。我检查了您的示例,实际上在删除它之后,它运行良好,没有任何编译错误或警告。事实上,这是正确的解决方案。请你更新你的答案,以便我能验证它?
(ItemReader<COR_ACC_ACCOUNT>) itemDictionary.getReader(AccountReader.class)
@Bean
public Step step() {
return stepBuilderFactory.get("step")
.<COR_ACC_ACCOUNT, Account>chunk(10)
.reader((ItemReader<COR_ACC_ACCOUNT>) itemDictionary.getReader(AccountReader.class))
.processor(accountProcessor)
.writer(new JsonWriter<>())
.build();
}
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableBatchProcessing
public class MyJob {
@Autowired
private JobBuilderFactory jobs;
@Autowired
private StepBuilderFactory steps;
@Bean
public ItemDictionary itemDictionary() {
return new ItemDictionary(Arrays.asList(new FooReader()));
}
@Bean
public ItemWriter<Bar> itemWriter() {
return null;
}
@Bean
public Step step() {
return steps.get("step")
.<Foo, Bar>chunk(5)
.reader(itemDictionary().getReader(Foo.class))
.writer(itemWriter())
.build();
}
@Bean
public Job job() {
return jobs.get("job")
.start(step())
.build();
}
public class ItemDictionary {
private Map<Class, ItemReader> itemReaders;
public ItemDictionary(final List<ItemReader> readers) {
itemReaders = readers.stream().collect(Collectors.toMap(
ItemReader::getClass,
Function.identity()
));
}
public <I> ItemReader<I> getReader(final Class clazz) {
return itemReaders.get(clazz);
}
}
class Foo { }
class Bar { }
class FooReader implements ItemReader<Foo> {
@Override
public Foo read() {
return null;
}
}
}