在我的Web应用程序中,我启动并管理了几十个用于长期运行的spring-batch进程。
在我看来,spring-batch是在Web应用程序上下文中而不是在作业上下文中构建作业,从而导致非提示性错误“没有为作用域名称“步骤”注册任何作用域”。
有什么想法我想念的吗?
发布问题以来进行的更改/更新:
登录...
taskExecutor-1 2019-02-12 13:31:32,836 ERROR o.s.b.c.s.AbstractStep - Encountered an error executing step step0002-init-prepareGraphDatastore in job hierarchy-analyser
java.lang.IllegalStateException: No Scope registered for scope name 'step'
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:350) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) ~[spring-aop-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:672) ~[spring-aop-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at com.xxxx.MyExampleReader$$EnhancerBySpringCGLIB$$b0c58048.beforeStep(<generated>) ~[relationship-analyzer-tool-BASELINE.jar:na]
at org.springframework.batch.core.listener.CompositeStepExecutionListener.beforeStep(CompositeStepExecutionListener.java:77) ~[spring-batch-core-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:199) ~[spring-batch-core-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) [spring-batch-core-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68) [spring-batch-core-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67) [spring-batch-core-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) [spring-batch-core-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) [spring-batch-core-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:136) [spring-batch-core-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:313) [spring-batch-core-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:144) [spring-batch-core-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_162]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_162]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_162]
春季批量作业XML ...
<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="false"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:batch="http://www.springframework.org/schema/batch"
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-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">
<description>Hierarchy Analyzer</description>
<context:component-scan
base-package="com.xxxx.*" />
<bean class="org.springframework.batch.core.scope.JobScope" />
<bean class="org.springframework.batch.core.scope.StepScope" />
<batch:job id="hierarchy-analyser">
<batch:listeners>
<batch:listener
ref="someJobListeners" />
</batch:listeners>
<batch:step id="step0002-init-long-running-process"
allow-start-if-complete="true">
<batch:tasklet
transaction-manager="jtaTransactionManager" start-limit="100">
<batch:chunk reader="myExampleReader"
writer="myExampleWriter" commit-interval="1" />
</batch:tasklet>
<batch:fail on="FAILED" />
<batch:next on="*"
to="step0002-1-more-stuff" />
<batch:listeners>
<batch:listener ref="myExampleReader" />
<batch:listener ref="myExampleWriter" />
</batch:listeners>
</batch:step>
</batch:job>
</beans>
MyExampleReader ...
@Component
@Scope(value = "step", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyExampleReader
implements ItemReader<TableMetadata>,
StepExecutionListener { ... }
启动工作的代码...
private ResultWrapper<Job> setupJobById(Resource r) throws Exception {
ResultWrapper<Job> result = new ResultWrapper<Job>();
try {
Resource[] res = new Resource[] { r };
ClasspathXmlApplicationContextsFactoryBean b = new ClasspathXmlApplicationContextsFactoryBean();
b.setApplicationContext(applicationContext);
b.setResources(res);
ApplicationContextJobFactory factory = new ApplicationContextJobFactory(
r.getFilename().substring(0, r.getFilename().lastIndexOf('.')), b.getObject()[0]);
result.succeed(factory.createJob());
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
result.fail(null, ex.getMessage(), ex);
}
return result;
}
在AbstractBeanFactory.doGetbean()内部,这是spring上下文的内容:
{request=org.springframework.web.context.request.RequestScope@3e707e1c, session=org.springframework.web.context.request.SessionScope@375463f}
更新:回答的说明
导致此问题的代码有很多。
我要查找的类不在作业中的任何上下文扫描路径中,而是在全局上下文扫描路径中。公共论坛的消毒代码对任何响应者都是隐藏的。
原始代码未在整个应用程序中遵循一致的代理模式实践。没有理由不遵循一致的最佳实践。
不正确使用作业注册表内部组件会导致普遍的“困惑”。
关于原始问题中的“为什么”,答案是Spring在每个上下文的上下文扫描时评估范围。如果未在作业上下文中加载Bean(例如,由于job.xml文件缺少所需的类路径之一),则在延迟加载时,Spring会尝试加载Bean,并在父类路径中找到一个,恰好是通过网络配置扫描的一个。 Bean被声明为“ Step”。 webconfig当然没有步骤范围。
错误消息既正确(英语:Yo dude,此bean被声明为step作用域,但上下文中没有一个),并且具有误导性(我在工作中看到有step作用域,它正在执行中)步骤范围,其他Bean在步骤范围内操作,WTH ??? !!!!!)。
我希望看到更多从Spring返回的智能错误消息。一次追寻完全准确但完全隐藏问题根源的错误消息很容易一次浪费几天的时间。
答案 0 :(得分:2)
您在您的阅读器范围内使用proxyMode = ScopedProxyMode.TARGET_CLASS
,因此需要使用以下步骤声明步骤范围:
<beans:bean class="org.springframework.batch.core.scope.StepScope">
<beans:property name="proxyTargetClass" value="true" />
</beans:bean>
编辑:我知道在混合Java配置和XML配置(请参阅BATCH-2351)时没有被代理的bean有一个未解决的问题,但是我不确定您是否在这里遇到了这个问题。
以下是我会尝试的几件事:
<context:component-scan base-package="com.xxxx.*" />
和MyExampleReader
后,不要使用scope="step"
并使用带有@Component
的XML声明@Scope(value = "step", proxyMode = ScopedProxyMode.TARGET_CLASS)
JobLauncher
和Job
来启动。您可以在此处找到示例:https://docs.spring.io/spring-batch/4.1.x/reference/html/job.html#runningJobsFromWebContainer 可以在这里找到类似的问题:Spring batch scope issue while using spring boot
希望这会有所帮助。