2016-11-09 7 views
1

は、私は私の春バッチItemReaderにサービスやDAO Beanを注入しようとしている1つの更新を注入豆

については、以下を参照してください。しかし、注入された参照はNULLです。 XMLファイルで@Autowireと明示的なBean設定を使って試しました。

ジョブは、spring-mvcアプリケーションから実行されています。このItemReaderは、処理するIDのリストをロードするためにDBアクセスを必要とします。このリストを通してリーダが読み込み、ItemWriterは、既存のサービスとDAOレイヤを使用して各IDのデータベースに対して必要な変更を行います。ここで

は、このバージョンでは、私が注入しようとしている、また、私の構成(それが別々のスプリングbatch.xmlファイルに定義されているアプリケーションコンテキストXMLファイルの後のweb.xmlに含まれています。)

ですXML構成を使用してItemReaderにJobService Beanを追加します。

ここでの一般的な問題は、他のDAOやサービスをアイテムリーダやライターに挿入する方法ですか?

<beans:bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"> 
    <beans:property name="dataSource" ref="dataSourceJNDI" /> 
    <beans:property name="transactionManager" ref="transactionManager" /> 
    <beans:property name="databaseType" value="mysql" /> 
</beans:bean> 

<beans:bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher"> 
    <beans:property name="jobRepository" ref="jobRepository" /> 
</beans:bean> 

<beans:bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry" /> 

<beans:bean id="myItemReader" class="my.MyItemReader" scope="step"> 
    <beans:property name="jobService"> 
     <beans:bean class="my.JobService"></beans:bean> 
    </beans:property> 
</beans:bean> 

<job id="assignLeadBatch" restartable="false" job-repository="jobRepository"> 
    <step id="step1"> 
     <tasklet transaction-manager="dbOpsTransactionManager"> 
      <chunk reader="myItemReader" writer="myItemWriter" commit-interval="10" /> 
     </tasklet> 
    </step> 
</job> 

<beans:bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor"> 
    <beans:property name="jobRegistry" ref="jobRegistry" /> 
</beans:bean> 

ItemReader:

@Scope(value = "step", proxyMode = ScopedProxyMode.INTERFACES) 
@Component 
public class MyItemReader implements ItemReader<Integer> { 

    JobService jobService; 

    private List<Integer> itemsList; 

    @Autowired 
    public AssignLeadsJobItemReader(@Value("#{jobParameters['jobKey']}") final String jobKey) { 

     MyJob alj = jobService.loadByKey(jobKey); 

     itemsList = new ArrayList<AssignLeadsJobItem>(); 

     for(Integer i : myJob.getIdList()) {    
      itemsList.add(i); 
     } 
    } 

    @Override 
    public Integer read(){ 
     if(itemsList == null || itemsList.size() == 0) { 
      return null; 
     } else { 
      return itemsList.remove(0); 
     } 
    } 

    public JobService getJobService() { 
     return jobService; 
    } 

    public void setJobService(JobService jobService) { 
     this.jobService = jobService; 
    } 
} 

ジョブサービス:

@Service 
@Transactional 
public class JobService { 
    @Autowired 
    protected JobDAO jobDao; 

    @Autowired 
    protected SpringBatchService springBatchService; 

    public JobExecution startJob(String jobName, String jobKey) {  
      // Defined in a different Class without transactions. 
      return springBatchService.startJob("job_name", jobKey); 
    } 

    public MyJob loadByKey(String jobKey) { 
      return jobDao.loadByKey(jobKey); 
    } 
} 

UPDATE 1 このエラーは、ItemReaderコンストラクタの参照を呼び出すことによって発生していることに気付きました。私はこのコードを次のように変更しました:

@Scope(value = "step", proxyMode = ScopedProxyMode.INTERFACES) 
@Component 
public class MyItemReader implements ItemReader<Integer> { 
    private JobService jobService; 
    private List<Integer> itemsList; 
    private String jobKey; 

    @Autowired 
    public MyItemReader(@Value("#{jobParameters['jobKey']}") final String jobKey) { 
     this.jobKey = jobKey; 
     this.itemsList = null; 
    } 

    @Override 
    public Integer read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException { 
     // ugly ugly ugly 
     if (itemsList == null) { 
      itemsList = new ArrayList<Integer>(); 

      MyJob jobData = jobService.loadByKey(jobKey); 

      for (Integer i : jobData.getIdList()) { 
       itemsList.add(i); 
      } 
     } 

     if (itemsList.isEmpty()) { 
      return null; 
     } else { 
      return itemsList.remove(0); 
     } 
    } 
} 

コンストラクタでその醜い初期化を行う方法はありますか?

+0

job.serviceをシングルトンとして宣言し、property-ref –

+0

Thanks @ Lucaを使用してリーダーに配線します。私はyorの提案に従ってコードを変更しました。私はさらに、ItemReaderのコンストラクタでDAOを呼び出していることに問題があることに気付きました。 read()メソッドでarrayList(DAOから)を初期化するように変更しました。最初にList == nullかどうかをチェックし、そうであればそれを初期化し、次に要素を返します。しかし、この初期化はコンストラクタ上になければならないため、これは扱いにくいようです。そこからそれを動作させる方法はありますか?また、私はそれを受け入れることができるように、あなたのコメントの回答をしてください! – tggm

答えて

1

私は次の操作を行いたい:JobService

  • がリストに
  • あなたの読者を投入するためにfinalクラス変数へ

  • 使用InitializingBeanインターフェースをitemListjobKeyを作る

    • Autowireを次のようになります。

      @Scope(value = "step", proxyMode = ScopedProxyMode.INTERFACES) 
      @Component 
      public class MyItemReader implements ItemReader<Integer>, InitializingBean { 
      
          private final List<Integer> itemsList = new ArrayList<AssignLeadsJobItem>(); 
      
          @Autowired 
          private JobService jobService; 
      
          private final String jobKey; 
      
          @Autowired 
          public MyItemReader(@Value("#{jobParameters['jobKey']}") final String jobKey) { 
           this.jobKey = jobKey; 
          } 
      
          @Override 
          public Integer read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException { 
           if(itemsList.size() == 0) { 
            return null; 
           } else { 
            return itemsList.remove(0); 
           } 
          } 
      
          @Override 
          public void afterPropertiesSet() { 
           MyJob myJob = jobService.loadByKey(jobKey); 
           for(Integer id : myJob.getIdList()) {    
            itemsList.add(id); 
           } 
          } 
      } 
      
  • +0

    私のリーダーでautowiredサービスにアクセスすると、私はnullポインタで同様の問題が発生しました。あなたはなぜ私がafterPropertiesSetからサービスの呼び出しを行う必要があるか説明することができますか?これは今私のために働いていますが、理由は不明です。 –

    +0

    読者にInitializingBeanを実装すると、それらのステップでInitializingBeanも実装していない限り、プロセッサとライターをスキップするようです。それは期待される行動ですか? –

    +0

    まったくそうではなく、過去に見たこともありません。何か他のことが起こっているに違いありません。私はあなたの 'itemsList'が空であると仮定しているので、ステップはそれが何の仕事もないと信じています。 –

    関連する問題