如何在配置Spring作业时使用Spring Profiles

时间:2017-12-22 01:29:46

标签: spring spring-batch spring-profiles

我需要运行一个Spring批处理作业。我的要求是按顺序/并行运行几个步骤,具体取决于弹簧轮廓

我将Job配置放在spring配置文件中并行运行步骤 parallel.xml

<job id="job" xmlns="http://www.springframework.org/schema/batch"
incrementer="incrementer">

<step id="step1" next="step2">
    <tasklet ref="tasklet" />
</step>

<split id="step2" task-executor="assetStepAsyncTaskExecutor">
    <flow>
        <step id="split1">
            <tasklet ref="tasklet" />
        </step>
    </flow>
    <flow>
        <step id="split2">
            <tasklet ref="tasklet" />
        </step>
    </flow>
</split>
<listeners>
    <listener ref="listener" />
</listeners>
</job>

和Job配置在spring配置文件default.xml

中按顺序运行步骤
<job id="job" xmlns="http://www.springframework.org/schema/batch"
incrementer="incrementer">

<step id="step1" next="step2">
    <tasklet ref="tasklet" />
</step>
<step id="step2" next="step3">
            <tasklet ref="tasklet" />
</step>
<step id="step3">
    <tasklet ref="tasklet" />
</step>
<listeners>
    <listener ref="listener" />
</listeners>
</job>

我正在使用Spring配置文件在工作配置之间切换。

<beans profile="parallel">
<import resource="classpath:/spring/parallel.xml" />
</beans>

<beans profile="default">
<import resource="classpath:/spring/default.xml" />
</beans>

我通过web.xml中的contextConfigLocation context-param加载配置文件。

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
// other config files
classpath*:/spring/default.xml
classpath*:/spring/parallel.xml
</param-value>
</context-param>

我将个人资料详细信息作为context-params

传递
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>default</param-value>
</context-param>

<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>parallel</param-value>
</context-param>

如果我没有在contextConfigLocation中包含文件,那么它不会在default.xml和parallel.xml中加载spring bean,因此我得到NoBeanFoundException

Error creating bean with name 'controller' defined in class path resource [config.xml]: Cannot resolve reference to bean 'batchJob' while setting bean property 'job'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'batchJob' is defined
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1325) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1086) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:3339) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:3780) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at org.jboss.as.web.deployment.WebDeploymentService.doStart(WebDeploymentService.java:163) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
    at org.jboss.as.web.deployment.WebDeploymentService.access$000(WebDeploymentService.java:61) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
    at org.jboss.as.web.deployment.WebDeploymentService$1.run(WebDeploymentService.java:96) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [rt.jar:1.8.0_121]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [rt.jar:1.8.0_121]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_121]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_121]
    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_121]
    at org.jboss.threads.JBossThread.run(JBossThread.java:122)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'batchJob' is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:527) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1083) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:274) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    ... 26 more

如果我同时包含配置文件。我得到一个DuplicateJobException。

12/21/2017 17:00:58,971 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/]] (ServerService Thread Pool -- 85) JBWEB000287: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener: java.lang.IllegalStateException: org.springframework.batch.core.configuration.DuplicateJobException: A job configuration with this name [batchJob] was already registered
    at org.springframework.batch.core.configuration.support.AutomaticJobRegistrar.start(AutomaticJobRegistrar.java:164) [spring-batch-core-2.1.8.RELEASE.jar:]
    at org.springframework.batch.core.configuration.support.AutomaticJobRegistrar.onApplicationEvent(AutomaticJobRegistrar.java:128) [spring-batch-core-2.1.8.RELEASE.jar:]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:97) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:303) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:911) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:428) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:3339) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:3780) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at org.jboss.as.web.deployment.WebDeploymentService.doStart(WebDeploymentService.java:163) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
    at org.jboss.as.web.deployment.WebDeploymentService.access$000(WebDeploymentService.java:61) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
    at org.jboss.as.web.deployment.WebDeploymentService$1.run(WebDeploymentService.java:96) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [rt.jar:1.8.0_121]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [rt.jar:1.8.0_121]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_121]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_121]
    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_121]
    at org.jboss.threads.JBossThread.run(JBossThread.java:122)
Caused by: org.springframework.batch.core.configuration.DuplicateJobException: A job configuration with this name [batchJob] was already registered
    at org.springframework.batch.core.configuration.support.MapJobRegistry.register(MapJobRegistry.java:52) [spring-batch-core-2.1.8.RELEASE.jar:]
    at org.springframework.batch.core.configuration.support.DefaultJobLoader.doLoad(DefaultJobLoader.java:152) [spring-batch-core-2.1.8.RELEASE.jar:]
    at org.springframework.batch.core.configuration.support.DefaultJobLoader.load(DefaultJobLoader.java:114) [spring-batch-core-2.1.8.RELEASE.jar:]
    at org.springframework.batch.core.configuration.support.AutomaticJobRegistrar.start(AutomaticJobRegistrar.java:161) [spring-batch-core-2.1.8.RELEASE.jar:]
    ... 19 more

我错过了什么?

2 个答案:

答案 0 :(得分:0)

Spring Batch每个作业名称必须是唯一的,定义为id =&#34; job&#34;在配置作业时。以上配置尝试设置两个作业名相同的作业,如#34; batchJob&#34;这就是你看到异常的原因。

为了达到你的需要,你可以做到这一点。

 <job id="jobA" xmlns="http://www.springframework.org/schema/batch"
incrementer="incrementer">

<step id="step1" next="step2">
    <tasklet ref="tasklet" />
</step>

<split id="step2" task-executor="assetStepAsyncTaskExecutor">
    <flow>
        <step id="split1">
            <tasklet ref="tasklet" />
        </step>
    </flow>
    <flow>
        <step id="split2">
            <tasklet ref="tasklet" />
        </step>
    </flow>
</split>
<listeners>
    <listener ref="listener" />
</listeners>
</job>


<job id="jobB" xmlns="http://www.springframework.org/schema/batch"
incrementer="incrementer">

<step id="step1" next="step2">
    <tasklet ref="tasklet" />
</step>
<step id="step2" next="step3">
            <tasklet ref="tasklet" />
</step>
<step id="step3">
    <tasklet ref="tasklet" />
</step>
<listeners>
    <listener ref="listener" />
</listeners>
</job>

从您的控制器,您可以根据上下文参数调用jobA或jobB。

答案 1 :(得分:0)

正如@lzagkaretos在评论中提出的,问题出在Spring版本上。将版本更新到3.2.2.RELEASE为我解决了这个问题。