Spring Batch @StepScope无法生成CGLIB子类 [英] Spring Batch @StepScope cannot generate CGLIB subclass
问题描述
编辑
我创建了一个复制问题的测试项目。它可以在 https://github.com/tomverelst/test-batch 找到。
I created a test project that replicates the issue. It can be found at https://github.com/tomverelst/test-batch.
首先运行maven命令 exec:java
以启动HSQL数据库。然后,您可以运行JUnit测试 MigrationJobConfigurationTest
来加载Spring应用程序上下文。
First run the maven command exec:java
to start a HSQL database. Then you can run the JUnit test MigrationJobConfigurationTest
to load the Spring application context.
原始问题
启动Spring Batch应用程序时,Spring加载我的作业配置时出现以下异常:
When starting my Spring Batch application, I get the following exception when Spring is loading my job's configuration:
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代理的来源。
This is caused by the @StepScope
annotation in my job's configuration. It attempts to proxy a class with CGLIB which is already proxied with a JDK proxy and I don't know where this JDK proxy is coming from.
我也尝试过使用 @Scope(value =step,proxyMode = ScopedProxyMode.NO)
,但是在调用JDK代理时会出现堆栈溢出错误,该代理不断调用自身。
I have also tried using @Scope(value = "step", proxyMode = ScopedProxyMode.NO)
, but then I get a stack overflow error when invoking the JDK proxy, which keeps invoking itself.
如果我删除 @StepScope
注释,应用程序会正确启动,但我需要能够将它们用于我的工作。
The application starts correctly if I remove the @StepScope
annotations, but I need to be able to use them for my jobs.
春季配置
<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
...
MigrationJobConfiguration
@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)
- 读者的CGLIB子类被创建并注册为
reader
,而原始bean注册为scopedTarget.reader
。 -
StepScope
启动和后处理步骤
范围内的bean。它检测到CGLIB扩展阅读器
定义并尝试为其创建代理=> 错误。
@Configuration
definition reader sees@StepScope
annotation which is annotated with@Scope(value = "step", proxyMode = ScopedProxyMode.TARGET_CLASS)
- CGLIB subclass of reader is created and registered as
reader
while the original bean is registered asscopedTarget.reader
. StepScope
kicks in and post-processesstep
scoped beans. It detects the CGLIB extendedreader
definition and tries to create proxy for that => ERROR.
冲突中有两种代理机制。有一些非常奇怪的事情,在我看来,这永远不会奏效。将尝试搜索Spring JIRA。
There are two proxying mechanisms in conflict. There is something really weird going on and it seems to me that this can never work. Will try to search through Spring JIRA.
更新
找到解决方案 - 您需要禁用自动代理:
Found solution - you need to disable auto-proxying for the step scope:
<bean class="org.springframework.batch.core.scope.StepScope">
<property name="autoProxy" value="false" />
</bean>
这篇关于Spring Batch @StepScope无法生成CGLIB子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!