在注释驱动配置中对弹簧批组件进行范围调整的正确方法是什么?

时间:2015-09-09 19:09:33

标签: java spring spring-mvc spring-batch

我正在构建一个围绕spring MVC的应用程序,该应用程序包含spring-batch,它以类似于spring-batch-admin的方式动态管理批处理过程。我正在尝试使用spring-batch-admin作为基础来理解正在发生的事情,将上下文初始化转换为注释驱动的配置。

虽然应用程序尽可能使用注释驱动配置,但弹出批处理作业被外部化为XML文件。

启动时,AppInitializer在ClasspathXmlApplicationContextsFactoryBean正确初始化后尝试刷新上下文时失败。我知道bean已经被正确初始化,因为它试图加载其中一个作业,并且找不到步骤范围的bean。 (该过程不应该加载和执行作业,它只能在此时找到它们。)

作业本身在spring-batch-admin下正常工作,因此作业没有问题。

我确信我只是误解了不同部分的背景,解决方案取决于将部分放入正确的背景中。有谁可以指出我错过了什么?

环境:

Java 1.8
Spring 4.1.6
Spring-batch 3.0.2
Pivotal TC Developer Edition v3.0

提前致谢

日志摘录:

DEBUG DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@425cccc3: defining beans [org.springframework.batch.core.scope.JobScope#0,org.springframework.batch.core.scope.StepScope#0,org.springframework.beans.factory.config.CustomEditorConfigurer,org.springframework.batch.core.configuration.xml.CoreNamespacePostProcessor,batch_state_transition_comparator,step0002-fetch,step0003-archive-purge,org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean#0,archive-purge-mt]; parent: org.springframework.beans.factory.support.DefaultListableBeanFactory@51ae827
WARN  AnnotationConfigWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'step0002-fetch': Cannot resolve reference to bean 'sourceSelectionReader' while setting bean property 'itemReader'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'sourceSelectionReader' is defined
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'sourceSelectionReader' is defined
    at 
...

sourceSelectionReader Bean

@Component("sourceSelectionReader")
@Scope(value = "step", proxyMode = ScopedProxyMode.DEFAULT)
public class SourceSelectionReaderImpl implements ItemReader<TreeModel>,
        ApplicationContextAware, StepExecutionListener, SourceSelectionReader {

AppInitializer:

    public class AppInitializer implements WebApplicationInitializer {

        @Override
        public void onStartup(ServletContext container) throws ServletException {
            Logger logger = LoggerFactory.getLogger(this.getClass());


    AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
    rootContext.register(MyConfig.class);
    rootContext.refresh();

    // Manage the lifecycle of the root appcontext
    container.addListener(new ContextLoaderListener(rootContext));
    container.setInitParameter("defaultHtmlEscape", "true");


    AnnotationConfigWebApplicationContext jobExecutionContext = new AnnotationConfigWebApplicationContext();
    jobExecutionContext.setParent(rootContext);
    jobExecutionContext.register(ExecutionContextConfig.class);
    jobExecutionContext.refresh();


    AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();
    mvcContext.register(ViewConfig.class);
    mvcContext.setServletContext(container);

... (snip) ...          
        }
    }

2 个答案:

答案 0 :(得分:0)

我认为您应该使用@Scope(value="step", proxyMode=ScopedProxyMode.TARGET_CLASS)或其快捷方式@StepScope

答案 1 :(得分:0)

PICNIC错误:我使用了错误的范例。深入一点,我发现我试图使用的JobRegistry组件意味着直接从类路径加载和执行。我使用DefaultBatchConfigurer进行了重构,然后继续讨论下一个问题。