Spring 批量通配符 ItemWriter
Spring Batch Wildcard ItemWriter
我有一个虚拟问题。
为了解释我的 use-case,我有不同类型的 DAO;说用户,啤酒......等等。我想为所有这些使用一个通用的ItemWriter。我在定义的地方创建了一个 CommonComponentConfiguration
;
@Bean
@Qualifier(WRITER_INSERT_TO_DATABASE_BEAN)
public ItemWriter<?> insertDbItemWriter(@Qualifier(DATA_SOURCE) DataSource dataSource,
@Qualifier("insertSql") String insertSql) {
return new MyItemWriter<>(dataSource, insertSql);
}
作者class是这样写的;
@Slf4j
public class MyItemWriter<T> extends JdbcBatchItemWriter<T> {
public MyItemWriter(DataSource dataSource, String sql) {
this.setDataSource(dataSource);
this.setSql(sql);
this.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
this.setAssertUpdates(false);
}
@Override
public void write(List<? extends T> items) {
try {
super.write(items);
} catch (Exception e) {
log.error("Could not write the items " + items);
log.error(e.getMessage());
}
}
}
到目前为止一切正常。
事情变得复杂的地方是,我为每个定义存储库特定项目的存储库单独配置 classes。例如为用户插入数据库的步骤。
@Bean
@Qualifier(STEP_INSERT_TO_DB_BEAN)
public Step insertToDbStep(@Qualifier(READER_LOADED_INPUT_DATA_BEAN) ListItemReader<User> sourceItemReader, UserInsertProcessor userInsertProcessor, @Qualifier(WRITER_INSERT_TO_DATABASE_BEAN)
ItemWriter<User> dbItemWriter) {
return stepBuilderFactory.get("processInsertStep").<User, User>chunk(100)
.reader(sourceItemReader)
.processor(userInsertProcessor)
.writer(dbItemWriter)
.build();
}
当我在 IJ 中编写此代码时抱怨 Could not autowire. Qualified bean must be of 'ItemWriter<User>' type.
,但天哪,当我执行代码时,它可以工作,并且可以执行它应该执行的操作。当我调试时,它绑定了正确的东西。
好吧,你可能会说,如果有用就别碰它。不过我真的很想知道幕后发生了什么。
此外,如果您发现设计中的缺陷(例如尝试对所有事物都使用一种通用的东西),我们非常欢迎您提出建议。
提前谢谢你。
PS:
看到下面的这个线程,看起来非常相似 - 如果不是相同的话。但是我想知道这里是否与泛型有关。
IntelliJ IDEA shows errors when using Spring's @Autowired annotation
编辑:
However I really want to know what's happening behind the curtains.
对于这个 IntelliJ IDEA 警告,你是对的,它与 IntelliJ IDEA shows errors when using Spring's @Autowired annotation 中讨论的问题相同(也正如 Eugene 在评论中所解释的那样)
Also, if you see a flaw in the design (such as trying to use one common thing for everything), your suggestions are more than welcomed.
如果当前方法适合您,您可以使用它。但是,我建议让一件事做一件事并且做好。在您的情况下,这将为每个域类型使用一个项目编写器并将这些编写器包装在 ClassifierCompositeItemWriter 中。 composite writer使用一个Classifier
对item进行分类,并调用相应的writer。
我有一个虚拟问题。
为了解释我的 use-case,我有不同类型的 DAO;说用户,啤酒......等等。我想为所有这些使用一个通用的ItemWriter。我在定义的地方创建了一个 CommonComponentConfiguration
;
@Bean
@Qualifier(WRITER_INSERT_TO_DATABASE_BEAN)
public ItemWriter<?> insertDbItemWriter(@Qualifier(DATA_SOURCE) DataSource dataSource,
@Qualifier("insertSql") String insertSql) {
return new MyItemWriter<>(dataSource, insertSql);
}
作者class是这样写的;
@Slf4j
public class MyItemWriter<T> extends JdbcBatchItemWriter<T> {
public MyItemWriter(DataSource dataSource, String sql) {
this.setDataSource(dataSource);
this.setSql(sql);
this.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
this.setAssertUpdates(false);
}
@Override
public void write(List<? extends T> items) {
try {
super.write(items);
} catch (Exception e) {
log.error("Could not write the items " + items);
log.error(e.getMessage());
}
}
}
到目前为止一切正常。 事情变得复杂的地方是,我为每个定义存储库特定项目的存储库单独配置 classes。例如为用户插入数据库的步骤。
@Bean
@Qualifier(STEP_INSERT_TO_DB_BEAN)
public Step insertToDbStep(@Qualifier(READER_LOADED_INPUT_DATA_BEAN) ListItemReader<User> sourceItemReader, UserInsertProcessor userInsertProcessor, @Qualifier(WRITER_INSERT_TO_DATABASE_BEAN)
ItemWriter<User> dbItemWriter) {
return stepBuilderFactory.get("processInsertStep").<User, User>chunk(100)
.reader(sourceItemReader)
.processor(userInsertProcessor)
.writer(dbItemWriter)
.build();
}
当我在 IJ 中编写此代码时抱怨 Could not autowire. Qualified bean must be of 'ItemWriter<User>' type.
,但天哪,当我执行代码时,它可以工作,并且可以执行它应该执行的操作。当我调试时,它绑定了正确的东西。
好吧,你可能会说,如果有用就别碰它。不过我真的很想知道幕后发生了什么。
此外,如果您发现设计中的缺陷(例如尝试对所有事物都使用一种通用的东西),我们非常欢迎您提出建议。
提前谢谢你。
PS: 看到下面的这个线程,看起来非常相似 - 如果不是相同的话。但是我想知道这里是否与泛型有关。 IntelliJ IDEA shows errors when using Spring's @Autowired annotation
编辑:
However I really want to know what's happening behind the curtains.
对于这个 IntelliJ IDEA 警告,你是对的,它与 IntelliJ IDEA shows errors when using Spring's @Autowired annotation 中讨论的问题相同(也正如 Eugene 在评论中所解释的那样)
Also, if you see a flaw in the design (such as trying to use one common thing for everything), your suggestions are more than welcomed.
如果当前方法适合您,您可以使用它。但是,我建议让一件事做一件事并且做好。在您的情况下,这将为每个域类型使用一个项目编写器并将这些编写器包装在 ClassifierCompositeItemWriter 中。 composite writer使用一个Classifier
对item进行分类,并调用相应的writer。