Spring Batch @JobScope bean creation error “A bean with that name has already been defined”

huangapple go评论109阅读模式
英文:

Spring Batch @JobScope bean creation error "A bean with that name has already been defined"

问题

在我的Spring批处理项目中(Spring Boot版本为2.3.4.RELEASE,Java 1.8),我有一个处理器组件需要访问作业ID(用于跟踪目的)。我在bean声明中添加了@JobScope,这使我能够访问作业ID。

  1. @Component("dealerItemProcessor")
  2. @JobScope
  3. public class DealerItemProcessor implements ItemProcessor<Dealer, Dealer> {
  4. @Value("#{jobExecution}")
  5. private JobExecution jobExecution;
  6. @Override
  7. public Dealer process(final Dealer dealer) throws Exception {
  8. // 获取 jobExecution.getJobId(),处理数据的 bean
  9. }
  10. }

我在XML中声明了作业,如下所示:

  1. <job id="syncJob">
  2. <step id="step1">
  3. <tasklet>
  4. <chunk reader="itemReader"
  5. processor="dealerItemProcessor"
  6. writer="itemWriter" commit-interval="1"/>
  7. </tasklet>
  8. </step>
  9. <listeners>
  10. <listener ref="syncJobCompletionNotificationListener"/>
  11. </listeners>
  12. </job>

XML配置加载如下:

  1. @Configuration
  2. @EnableAutoConfiguration
  3. @ImportResource("classpath:batch-job.xml")
  4. public class XMLConfigurationLoader {
  5. }

作业是这样调度的:

  1. public SyncJobScheduler(@Qualifier("syncJob") Job dealerSyncJob,
  2. JobLauncher jobLauncher) {
  3. this.syncJob = syncJob;
  4. this.jobLauncher = jobLauncher;
  5. }
  6. @Scheduled(cron = "0 0 */1 * * *")
  7. public void schedule() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
  8. jobLauncher.run(syncJob, new JobParametersBuilder()
  9. .addDate("date", new Date())
  10. .toJobParameters());
  11. }

当我在Linux操作系统服务器和OpenJDK 1.8中构建和运行项目时,我会收到以下错误:

  1. ***************************
  2. APPLICATION FAILED TO START
  3. ***************************
  4. Description:
  5. The bean 'scopedTarget.dealerItemProcessor', defined in BeanDefinition defined in URL [jar:file:/var/www/jobs/upload-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/sync/connect/processor/DealerItemProcessor.class], could not be registered. A bean with that name has already been defined in URL [jar:file:/var/www/jobs/upload-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/sync/connect/processor/DealerItemProcessor.class] and overriding is disabled.
  6. Action:
  7. Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

我已经启用了调试模式并看到了相同的错误。我该如何排除此问题?你能给一些建议吗?

更新1:
我尝试将JobScope更改为StepScope,看到类似的异常。

  1. 2020-10-15 10:53:02.651 [DEBUG] [main] [org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter:37] Application failed to start due to an exception
  2. org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'scopedTarget.dealerItemProcessor' defined in BeanDefinition defined in URL [jar:file:/var/www/jobs/upload-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/sync/connect/processor/DealerItemProcessor.class]: Cannot register bean definition [Root bean: class [org.springframework.aop.scope.ScopedProxyFactoryBean]; scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in BeanDefinition defined in URL [jar:file:/var/www/jobs/upload-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/sync/connect/processor/DealerItemProcessor.class]] for bean 'scopedTarget.dealerItemProcessor': There is already [Generic bean: class [com.sync.connect.processor.DealerItemProcessor]; scope=step; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in URL [jar:file:/var/www/jobs/upload-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/sync/connect/processor/DealerItemProcessor.class]] bound.
英文:

In my Spring batch project (Spring Boot version 2.3.4.RELEASE, Java 1.8), I have a processor component that needs to access the Job Id (for tracking purpose). I added @JobScope to the bean declaration and this allows me to access the Job Id.

  1. @Component(&quot;dealerItemProcessor&quot;)
  2. @JobScope
  3. public class DealerItemProcessor implements ItemProcessor&lt;Dealer, Dealer&gt; {
  4. @Value(&quot;#{jobExecution}&quot;)
  5. private JobExecution jobExecution;
  6. @Override
  7. public Dealer process(final Dealer dealer) throws Exception {
  8. //Get jobExecution.getJobId(), process data bean
  9. }

I declared the Job in XML like this:

  1. &lt;job id=&quot;syncJob&quot; &gt;
  2. &lt;step id=&quot;step1&quot;&gt;
  3. &lt;tasklet&gt;
  4. &lt;chunk reader=&quot;itemReader&quot;
  5. processor=&quot;dealerItemProcessor&quot;
  6. writer=&quot;itemWriter&quot; commit-interval=&quot;1&quot;/&gt;
  7. &lt;/tasklet&gt;
  8. &lt;/step&gt;
  9. &lt;listeners&gt;
  10. &lt;listener ref=&quot;syncJobCompletionNotificationListener&quot;/&gt;
  11. &lt;/listeners&gt;
  12. &lt;/job&gt;

The XML configuration is loaded as:

  1. @Configuration
  2. @EnableAutoConfiguration
  3. @ImportResource(&quot;classpath:batch-job.xml&quot;)
  4. public class XMLConfigurationLoader {
  5. }

The Job is scheduled like this:

  1. public SyncJobScheduler(@Qualifier(&quot;syncJob&quot;) Job dealerSyncJob,
  2. JobLauncher jobLauncher) {
  3. this.syncJob = syncJob;
  4. this.jobLauncher = jobLauncher;
  5. }
  6. @Scheduled(cron = &quot;0 0 */1 * * *&quot;)
  7. public void schedule() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
  8. jobLauncher.run(syncJob, new JobParametersBuilder()
  9. .addDate(&quot;date&quot;, new Date())
  10. .toJobParameters());
  11. }

When I build and run the project in a Linux OS server and OpenJDK 1.8, I get the following error.

  1. ***************************
  2. APPLICATION FAILED TO START
  3. ***************************
  4. Description:
  5. The bean &#39;scopedTarget.dealerItemProcessor&#39;, defined in BeanDefinition defined in URL [jar:file:/var/www/jobs/upload-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/sync/connect/processor/DealerItemProcessor.class], could not be registered. A bean with that name has already been defined in URL [jar:file:/var/www/jobs/upload-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/sync/connect/processor/DealerItemProcessor.class] and overriding is disabled.
  6. Action:
  7. Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

I have enabled debug mode and see the same error. How can I troubleshoot this? Can you please give some pointers?

Update 1:
I tried changing JobScope to StepScope, and see a similar exception.
2020-10-15 10:53:02.651 [DEBUG] [main]

  1. [org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter:37] Application failed to start due to an exception
  2. org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name &#39;scopedTarget.dealerItemProcessor&#39; defined in BeanDefinition defined in URL [jar:file:/var/www/jobs/upload-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/sync/connect/processor/DealerItemProcessor.class]: Cannot register bean definition [Root bean: class [org.springframework.aop.scope.ScopedProxyFactoryBean]; scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in BeanDefinition defined in URL [jar:file:/var/www/jobs/upload-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/sync/connect/processor/DealerItemProcessor.class]] for bean &#39;scopedTarget.dealerItemProcessor&#39;: There is already [Generic bean: class [com.sync.connect.processor.DealerItemProcessor]; scope=step; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in URL [jar:file:/var/www/jobs/upload-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/sync/connect/processor/DealerItemProcessor.class]] bound.

答案1

得分: 0

你可以使用 @StepScope 替代 @JobScope。你可以使用 stepExecution.getJobExecution() 来获取 jobExecution。然后就像你提到的那样,你可以获得 jobId。

英文:

You can use @StepScope instead of @JobScope. You can use stepExecution.getJobExecution() to get the jobExecution. Then you as you have mentioned you can get the jobId.

答案2

得分: 0

  1. 我通过实现StepExecutionListener使这个工作起来了这样可以访问StepExecution对象从中我们可以获取到任务的Id
  2. @Component("dealerItemProcessor")
  3. public class DealerItemProcessor implements ItemProcessor<Dealer, Dealer>, StepExecutionListener {
  4. private StepExecution stepExecution;
  5. @Override
  6. public Dealer process(final Dealer dealer) throws Exception {
  7. // 像这样获取唯一的JobId - stepExecution.getJobExecutionId()
  8. // 处理逻辑
  9. }
  10. @Override
  11. public void beforeStep(StepExecution stepExecution) {
  12. // 获取stepExecution对象
  13. this.stepExecution = stepExecution;
  14. }
  15. @Override
  16. public ExitStatus afterStep(StepExecution stepExecution) {
  17. return null;
  18. }
  19. }
  20. 这个解决方案通过提供一个替代方法来解决了获取JobId的需求但它并没有解决问题中提到的Bean创建异常
英文:

I got this to work by implementing the StepExecutionListener. This gives access to the StepExecution object, from which we get the Job Id.

  1. @Component(&quot;dealerItemProcessor&quot;)
  2. public class DealerItemProcessor implements ItemProcessor&lt;Dealer, Dealer&gt; , StepExecutionListener {
  3. private StepExecution stepExecution;
  4. @Override
  5. public Dealer process(final Dealer dealer) throws Exception {
  6. //get unique JobId like this - stepExecution.getJobExecutionId()
  7. // process logic
  8. }
  9. @Override
  10. public void beforeStep(StepExecution stepExecution) {
  11. //get the stepExecution Object.
  12. this.stepExecution = stepExecution;
  13. }
  14. @Override
  15. public ExitStatus afterStep(StepExecution stepExecution) {
  16. return null;
  17. }
  18. }

This solution solves the need to get JobId by providing an alternate. It does not solve the Bean creation exception posted in the question.

huangapple
  • 本文由 发表于 2020年10月14日 03:20:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/64341830.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定