【发布时间】:2021-03-22 04:59:23
【问题描述】:
我目前正处于一个我似乎无法弄清楚的问题的真正痛苦之中。我希望这里有人可以提供一些指导。这一切都围绕着 StepScope、bean 自动装配和 bean 创建。
配置一(自动装配 Step Scope Beans):
Config.java
(为简单起见,我减少了配置类。)
@Configuration
@EnableBatchProcessing
public class Config {
@Bean
@StepScope
public StepScopeBeanOne stepScopeBeanOne() {
return new StepScopeBeanOne();
}
@Bean
@StepScope
public StepScopeBeanTwo stepScopeBeanTwo () {
return new StepScopeBeanTwo();
}
@Bean
@StepScope
public Processor processor() {
return new Processor();
}
}
处理器.java
public class Processor implements ItemProcessor<Incoming, Outgoing> {
//The two injected step scope beans...
@Autowired
private StepScopeBeanOne stepScopeBeanOne;
@Autowired
private StepScopeBeanTwo stepScopeBeanTwo;
@Override
public Outgoing process(Incoming incoming) {
//do process...
}
public void setStepScopeBeanTwo(StepScopeBeanTwo stepScopeBeanTwo) {
this.stepScopeBeanTwo = stepScopeBeanTwo;
}
public void setStepScopeBeanOne(StepScopeBeanOne stepScopeBeanOne) {
this.stepScopeBeanOne = stepScopeBeanOne;
}
//rest of class...
}
结果
org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为“scopedTarget.scopedTarget.Processor”的bean时出错:通过字段“stepScopeBeanOne”表示的依赖关系不满足;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有可用的“StepScopeBeanOne”类型的合格 bean:预计至少有 1 个有资格作为自动装配候选者的 bean。依赖注解:{@org.springframework.beans.factory.annotation.Autowired(required=true)}
我的想法
我认为这与解析处理器 bean 时 bean StepScopeBeanOne 不在 ApplicationContext 中有关。
配置二(Step Scope Beans的Setter注入)
Config.java
@Configuration
@EnableBatchProcessing
public class Config {
@Bean
@StepScope
public StepScopeBeanOne stepScopeBeanOne() {
return new StepScopeBeanOne();
}
@Bean
@StepScope
public StepScopeBeanTwo stepScopeBeanTwo () {
return new StepScopeBeanTwo();
}
@Bean
@StepScope
public Processor processor() {
Processor processor = new Processor();
processor.setStepScopeBeanOne(stepScopeBeanOne());
processor.setStepScopeBeanTwo(stepScopeBeanTwo());
return processor;
}
}
处理器与配置一相同
结果
org.springframework.beans.factory.BeanCreationException:在类路径资源 [Config.class] 中定义名称为“scopedTarget.scopedTarget.Processor”的 bean 创建错误:通过工厂方法进行 Bean 实例化失败;嵌套异常是 org.springframework.beans.BeanInstantiationException:无法实例化 [Processor]:工厂方法“处理器”抛出异常;嵌套异常是 java.lang.IllegalStateException:@Bean 方法 Config.stepScopeBeanOne 被称为类型 [StepScopeBeanOne] 的 bean 引用,但被类型 [com.sun.proxy.$Proxy149] 的不兼容 bean 实例覆盖。覆盖在类路径资源 [Config.class] 中定义的 BeanDefinition 中声明的同名 bean
我的想法
我之前遇到过这个问题,我的解决方法是为我正在注入的类创建一个接口。
public interface StepScopeBeanOne {
//methods
}
public class StepScopeBeanOneImpl implements StepScopeBeanOne {
//methods
}
我不想再走那条路,因为我相信它会增加代码的复杂性。如果有人有不同的解决方案,请分享。
配置三(有效的)
从这些 bean 中删除 Step Scope 会导致一个很好的自动装配。
配置类
@Configuration
@EnableBatchProcessing
public class Config {
@Bean
public StepScopeBeanOne stepScopeBeanOne() {
return new StepScopeBeanOne();
}
@Bean
public StepScopeBeanTwo stepScopeBeanTwo () {
return new StepScopeBeanTwo();
}
@Bean
public Processor processor() {
Processor processor = new Processor();
return processor;
}
}
处理器相同
结果
通过 @Autowiring 注解注入 Bean。
我的想法
您可能会问自己,为什么不直接删除 @StepScope?好吧,我不能。我需要对这些 bean 中的每一个进行 step 范围,以允许正确注入 JobParameters。我们在作业参数中使用步骤名称来提供微调的步骤配置。
总体
我的目标是让配置一正常工作。在这个目标之外,更好地理解 Spring 中的 bean 创建将不胜感激。
【问题讨论】:
-
您没有分享一个完整的最小示例来重现该问题,但我尝试过,但无法根据您分享的内容重现该问题。我用一个例子添加了一个答案。希望对您有所帮助。
标签: java spring spring-boot spring-batch