Spring Batch @StepScope无法生成CGLIB子类

2023-12-10

EDIT

我创建了一个测试项目来复制该问题。可以在以下位置找到:https://github.com/tomverelst/test-batch.

首先运行maven命令exec:java启动 HSQL 数据库。然后就可以运行JUnit测试了MigrationJobConfigurationTest加载 Spring 应用程序上下文。

原问题

启动 Spring Batch 应用程序时,当 Spring 加载我的作业配置时,出现以下异常:

Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy34]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy34

这是由于@StepScope我的作业配置中的注释。它尝试使用 CGLIB 代理一个类,该类已经使用 JDK 代理进行代理,但我不知道这个 JDK 代理来自哪里。

我也尝试过使用@Scope(value = "step", proxyMode = ScopedProxyMode.NO),但是在调用 JDK 代理时出现堆栈溢出错误,该代理不断调用自身。

如果我删除应用程序,应用程序将正确启动@StepScope注释,但我需要能够将它们用于我的工作。

弹簧配置

<context:component-scan base-package="com.jnj.rn2.batch" />

<context:annotation-config />

<aop:aspectj-autoproxy proxy-target-class="true" />

<bean class="org.springframework.batch.core.scope.StepScope" />

// Job repository etc
...

迁移作业配置

@Configuration
public class MigrationJobConfiguration {

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

    @Autowired
    private MigrationService migrationService;

    @Bean
    public Job migrationJob() {
        return jobs.get( "migrationJob" )
            .start( migrateCrfStep() )
            .next( indexRequestsStep() )
            .build();
    }

    @Bean
    public Step migrateCrfStep() {
        return steps.get( "migrateCrfStep" )
            .tasklet( migrateCrfTasklet() )
            .build();
    }

    @Bean
    public Step indexRequestsStep() {
        return steps.get( "indexRequestsStep" )
            .<LegacyRequest,LegacyRequest> chunk( 5 )
            .reader( indexRequestReader() )
            .processor( indexRequestProcessor() )
            .writer( indexRequestWriter() )
            .build();
    }

    @Bean
    @StepScope
    public MigrateCrfTasklet migrateCrfTasklet() {
        return new MigrateCrfTasklet();
    }

    @Bean
    @StepScope
    public IndexRequestItemReader indexRequestReader() {
        return new IndexRequestItemReader();
    }

    @Bean
    @StepScope
    public IndexRequestItemProcessor indexRequestProcessor() {
        return new IndexRequestItemProcessor();
    }

    @Bean
    @StepScope
    public IndexRequestItemWriter indexRequestWriter() {
        return new IndexRequestItemWriter();
    }

    // Setters
    ...
}

I can not provide you an actual answer (yet), but I've debugged the example you have provided and this is happening:

  • @Configuration读者看到的定义@StepScope注释 其注释为@Scope(value = "step", proxyMode = ScopedProxyMode.TARGET_CLASS)
  • reader 的 CGLIB 子类被创建并注册为reader而原始 bean 注册为scopedTarget.reader.
  • StepScope启动和后处理step范围内的bean。它检测CGLIB扩展reader定义并尝试为其创建代理=>ERROR.

有两种相互冲突的代理机制。发生了一些非常奇怪的事情,在我看来,这永远行不通。将尝试通过 Spring JIRA 进行搜索。


UPDATE

找到解决方案 - 你需要禁用自动代理对于步骤范围:

<bean class="org.springframework.batch.core.scope.StepScope">
    <property name="autoProxy" value="false" />
</bean>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Batch @StepScope无法生成CGLIB子类 的相关文章

随机推荐