gpt4 book ai didi

java - Spring Batch @StepScope 无法生成 CGLIB 子类

转载 作者:行者123 更新时间:2023-12-01 14:08:44 31 4
gpt4 key购买 nike

编辑

我创建了一个测试项目来复制这个问题。可以在 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 引起的我的工作配置中的注释。它尝试使用已经用 JDK 代理代理的 CGLIB 来代理一个类,但我不知道这个 JDK 代理来自哪里。

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

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

Spring 配置
<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
...
}

最佳答案

我无法为您提供实际答案(还),但我已经调试了您提供的示例,并且正在发生这种情况:

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

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

    更新

    找到解决方案 - 您需要 disable auto-proxying对于步骤范围:
    <bean class="org.springframework.batch.core.scope.StepScope">
    <property name="autoProxy" value="false" />
    </bean>

    关于java - Spring Batch @StepScope 无法生成 CGLIB 子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19159472/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com