2016-11-09 3 views
1

내가 내 스프링 배치 ItemReader에 서비스 또는 DAO 빈을 주입하기 위해 노력하고있어 1 업데이트를 주입 콩

은 아래를 참조하십시오. 그러나 삽입 된 참조는 NULL입니다. 나는 XML 파일에서 @Autowire와 명시 적 bean 설정을 사용하여 이것을 시도했다.

작업이 spring-mvc 응용 프로그램에서 실행되고 있습니다. 이 ItemReader는 처리 할 ID 목록을로드하려면 DB 액세스가 필요합니다. 이 목록을 통해 독자가 읽고 ItemWriter는 기존 서비스 및 DAO 레이어를 사용하여 각 ID에 대해 데이터베이스에서 필요한 변경을 수행합니다. 여기

는 (이 응용 프로그램 컨텍스트 XML 파일 후 web.xml 파일에 포함 된 별도의 스프링 batch.xml 파일에 정의되어 있습니다.)

또한, 나는이를 주입하기 위해 노력하고있어이 버전 내 구성의 XML 구성을 사용하여 JobReader에 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); 
     } 
    } 
} 

생성자에서 그 추한 초기화를 넣을 수있는 방법이 있나요 : 나는 thusly 히 코드를 변경?

+0

job.service를 싱글 톤으로 선언하고 property-ref –

+0

Thanks @ Luca를 사용하여 리더기에 연결합니다. yor 제안에 따라 코드를 변경했습니다. 그런 다음 문제는 ItemReader의 생성자에서 DAO를 호출한다는 것입니다. read() 메서드에서 DAO의 arrayList를 초기화하기 위해 작업을 변경했습니다. 그래서 List == null인지 먼저 검사하고, 그렇다면 초기화하고 요소를 반환합니다. 그러나 이것은 초기화가 생성자에 있어야하기 때문에 어색한 것으로 보입니다. 거기에서 작동하도록하는 방법이 있습니까? 또한, 내가 그것을 받아 들일 수 있도록 귀하의 의견에 대한 답변을하십시오! – tggm

답변

1

다음 작업을 수행 할 것 다음 JobService

  • 목록을
  • 이제

    독자를 채우는 데 final 클래스 변수로

  • 사용 InitializingBean 인터페이스를 itemListjobKey을 확인

    • 자동으로 묶어을 다음과 같이 보일 것입니다 :

      @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'가 비어 있다고 가정하고 있습니다, 그래서 그 단계는 그것이 할 일이 없다고 생각합니다. –