我有以下 Spring Boot 2 设置,并且仅当使用基于
BeanDefinitionOverrideException
的 bean 定义时,它才会在启动期间抛出 XML
,在使用基于 Java
的 bean 定义时以及在 @ImportResource 中使用相同的 XML 时,效果相同
请注意,目前无法升级到 SB3。
启动错误
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'scopedTarget.reader', defined in BeanDefinition defined in file [/Users/username/IdeaProjects/testing-spring-batch/target/classes/org/example/Reader.class], could not be registered. A bean with that name has already been defined in file [/Users/username/IdeaProjects/testing-spring-batch/target/classes/org/example/Reader.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
Main.java
@SpringBootApplication
@EnableBatchProcessing
public class Main {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Main.class);
app.setSources(Collections.singleton("classpath:launch-context.xml"));
System.exit(SpringApplication.exit(app.run(args).getParent()));
}
}
Reader.java
@Component
@StepScope
public class Reader implements ItemReader<String> {
// return a list of string
}
XML
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<batch:job id="test">
<batch:step id="companyStep">
<batch:tasklet>
<batch:chunk reader="reader" processor="processor"
writer="writer" commit-interval="1" />
</batch:tasklet>
</batch:step>
</batch:job>
</beans>
更新
我看到步骤作用域 bean poxy
scopedTarget.reader
在 Bean 定义注册表中注册了两次,一次是在 Spring 自动扫描注释时注册的,第二次是在调用 Step Scope 后处理器 (PP) 时注册的。
使用基于 Java 的配置时,Step Scope Bean PP 将自动代理标志设置为 false(在
ScopeConfiguration
类中),因此它不会代理 bean。
但是,在使用基于 XML 的定义时,StepScope 是使用本机构造函数创建的(通过
CoreNamespaceUtils
类' checkForScope
方法),导致创建重复的代理。
有什么办法可以避免这种行为吗?
注:
当我使用
@ImportResource("classpath:launch-context.xml")
导入 XML bean 源时,不会发生这种情况,因为在这种情况下,导入源中的 bean 仅在刷新应用程序上下文时(即解析 bean 定义后)进行处理。
就我而言,导入的资源是动态的。因此需要一种方法来动态传递此资源,寻找一种方法来做到这一点,直到理解OP中的问题为止。
my_path = {a xml path}
@ImportResource(locations = {"${my_path:your default value}"})