Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么可以';我将字符串参数传递给这个方法,而Spring不会抱怨Bean_Spring_Spring Batch - Fatal编程技术网

为什么可以';我将字符串参数传递给这个方法,而Spring不会抱怨Bean

为什么可以';我将字符串参数传递给这个方法,而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<

问题其实很简单,但我不明白为什么Spring会抱怨

我希望能够在每个步骤中向ItemReader传递不同的查询,但Spring抱怨getReader方法中的参数:

@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()
              ));
      }
  }