为什么可以';我将字符串参数传递给这个方法,而Spring不会抱怨Bean
问题其实很简单,但我不明白为什么Spring会抱怨 我希望能够在每个步骤中向ItemReader传递不同的查询,但Spring抱怨getReader方法中的参数:为什么可以';我将字符串参数传递给这个方法,而Spring不会抱怨Bean,spring,spring-batch,Spring,Spring Batch,问题其实很简单,但我不明白为什么Spring会抱怨 我希望能够在每个步骤中向ItemReader传递不同的查询,但Spring抱怨getReader方法中的参数: @Bean public JdbcCursorItemReader<Assessment> getReader(DataSource datasource, String query, String name) { return new JdbcCursorItemReaderBuilder<
@Bean
public JdbcCursorItemReader<Assessment> getReader(DataSource datasource, String query, String name) {
return new JdbcCursorItemReaderBuilder<Assessment>()
.dataSource(datasource)
.sql(query)
.name(name)
.rowMapper(new AssessmentMapper())
.build();
}
如果我从getReader()中删除@Bean注释,那么我会得到一个类似的输出,说明:
Description:
Parameter 2 of method step1 in com.batch.config.ExpirationUtilityConfig required a bean of type 'org.springframework.batch.item.ItemReader' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.batch.item.ItemReader' in your configuration.
不太明白这里发生了什么。。。我只是想把一个字符串传递给getReader()…简而言之,这就是您的问题所在
很简单,您有一个bean(jdbcursoritemreader),它需要两个字符串参数:
String query, String name
但是Spring没有在上下文中找到它们。任何bean需要的每个参数都必须在父/子上下文/配置中的某个地方定义
您希望查询和名称来自哪里?它们是否来自属性文件,它们是如何定义的
了解属性+属性文件
在任何情况下,假设您将它们定义到具有以下内容的属性文件中:
queryConfig.query=SELECT * from whatever;
queryConfig.queryName=someQueryName
或者,您可以在yaml文件中定义这些道具,将它们作为环境变量传递,或者您喜欢的任何东西,请查看以下链接以了解Spring提供了什么:
选择propertySource后要做什么
无论如何,一旦您以某种方式定义了查询和queryName,就应该开始在应用程序中使用它们了。首先要知道的是,让字符串参数四处飞行不是一个好的做法,因此您可能会自己将这两个道具捆绑在一个配置对象中,或者至少捆绑在一个类中,例如:
public class QueryProperties {
private String query;
private String queryName;
//...getters, setters and constructor (I usually use lombok so this is boilerplate for me)
}
然后ExpirationUtilityConfig应该类似于:
@Configuration
public class ExpirationUtilityConfig {
/**
* This is one of the ways to get the value of a property which is defined in a propertySource
*/
@Value("${queryConfig.query}") private String query;
@Value("${queryConfig.queryName}") private String queryName;
/**
* This will make sure you got a QueryPropeties object in your Spring config, which can be used (injected in) by the JdbcCursorItemReader below
*/
@Bean
public QueryProperties getQueryProperties() {
return new QueryProperties(query, queryName);
}
@Bean
public JdbcCursorItemReader<Assessment> getReader(DataSource datasource, QueryProperties queryProperties) {
return new JdbcCursorItemReaderBuilder<Assessment> ()
.dataSource(datasource)
.sql(queryProperties.getQuery()) // use the queryPropeties.getQuery() or simply query from @Value
.name(queryProperties.getQueryName())
.rowMapper(new AssessmentMapper())
.build();
}
@Bean
public Step step1(StepBuilderFactory factory,
DataSource dataSource,
ItemReader reader,
ExpireAssessmentWriter writer, //use custom writer
AssessmentItemProcessor processor,
PlatformTransactionManager platformTransactionManager) {
return stepBuilderFactory.get("step1")
.transactionManager(platformTransactionManager)
.<Assessment, Assessment> chunk(10)
.reader(getReader(dataSource, READER_QUERY, "AssessmentReader")
.processor(processor)
.writer(writer)
.build()
));
}
}
@配置
公共类过期实用程序配置{
/**
*这是获取propertySource中定义的属性值的方法之一
*/
@值(“${queryConfig.query}”)私有字符串查询;
@值(“${queryConfig.queryName}”)私有字符串queryName;
/**
*这将确保您在Spring配置中获得QueryProperties对象,下面的JdbcCursorItemReader可以使用(注入)该对象
*/
@豆子
公共查询属性getQueryProperties(){
返回新的QueryProperty(查询,queryName);
}
@豆子
公共JdbcCursorItemReader getReader(数据源数据源、查询属性QueryProperties){
返回新的JdbcCursorItemReaderBuilder()
.dataSource(数据源)
.sql(queryProperties.getQuery())//使用queryProperties.getQuery()或仅从@Value查询
.name(queryProperties.getQueryName())
.rowMapper(新的AssessmentMapper())
.build();
}
@豆子
公共步骤step1(StepBuilderFactory工厂,
数据源数据源,
项目阅读器,
expireasessmentwriter写入程序,//使用自定义写入程序
评估项目处理器,
平台事务管理器平台事务管理器){
返回stepBuilderFactory.get(“step1”)
.transactionManager(平台transactionManager)
.chunk(10)
.reader(getReader(数据源、reader\u查询、“AssessmentReader”)
.处理器(处理器)
.作者(作者)
.build()
));
}
}
这是否回答了您的问题?谢谢你,马哈茂德
public class QueryProperties {
private String query;
private String queryName;
//...getters, setters and constructor (I usually use lombok so this is boilerplate for me)
}
@Configuration
public class ExpirationUtilityConfig {
/**
* This is one of the ways to get the value of a property which is defined in a propertySource
*/
@Value("${queryConfig.query}") private String query;
@Value("${queryConfig.queryName}") private String queryName;
/**
* This will make sure you got a QueryPropeties object in your Spring config, which can be used (injected in) by the JdbcCursorItemReader below
*/
@Bean
public QueryProperties getQueryProperties() {
return new QueryProperties(query, queryName);
}
@Bean
public JdbcCursorItemReader<Assessment> getReader(DataSource datasource, QueryProperties queryProperties) {
return new JdbcCursorItemReaderBuilder<Assessment> ()
.dataSource(datasource)
.sql(queryProperties.getQuery()) // use the queryPropeties.getQuery() or simply query from @Value
.name(queryProperties.getQueryName())
.rowMapper(new AssessmentMapper())
.build();
}
@Bean
public Step step1(StepBuilderFactory factory,
DataSource dataSource,
ItemReader reader,
ExpireAssessmentWriter writer, //use custom writer
AssessmentItemProcessor processor,
PlatformTransactionManager platformTransactionManager) {
return stepBuilderFactory.get("step1")
.transactionManager(platformTransactionManager)
.<Assessment, Assessment> chunk(10)
.reader(getReader(dataSource, READER_QUERY, "AssessmentReader")
.processor(processor)
.writer(writer)
.build()
));
}
}