BATCH-1394: add support for SpEL with Spring 3.0 in step scope
This commit is contained in:
@@ -17,10 +17,12 @@ package org.springframework.batch.core.scope;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.aop.scope.ScopedProxyUtils;
|
||||
import org.springframework.batch.core.scope.context.StepContext;
|
||||
import org.springframework.batch.core.scope.context.StepSynchronizationManager;
|
||||
import org.springframework.batch.core.scope.util.PlaceholderProxyFactoryBean;
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
@@ -33,6 +35,7 @@ import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
|
||||
/**
|
||||
@@ -111,11 +114,17 @@ public class StepScope implements Scope, BeanFactoryPostProcessor, Ordered {
|
||||
public void setProxyTargetClass(boolean proxyTargetClass) {
|
||||
this.proxyTargetClass = proxyTargetClass;
|
||||
}
|
||||
|
||||
// Implement missing method from Spring 3.0 SPI.
|
||||
|
||||
/**
|
||||
* If Spring 3.0 is available, this will be used to resolve expressions in
|
||||
* step-scoped beans. This method is part of the Scope SPI in Spring 3.0,
|
||||
* but should just be ignored by earlier versions of Spring.
|
||||
*/
|
||||
public Object resolveContextualObject(String key) {
|
||||
StepContext context = getContext();
|
||||
return context.getAttribute(key);
|
||||
// TODO: support for attributes as well maybe (setters not exposed yet
|
||||
// so not urgent).
|
||||
return new BeanWrapperImpl(context).getPropertyValue(key);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,13 +219,19 @@ public class StepScope implements Scope, BeanFactoryPostProcessor, Ordered {
|
||||
Scopifier scopifier = new Scopifier(registry, name, proxyTargetClass, scoped);
|
||||
scopifier.visitBeanDefinition(definition);
|
||||
if (scoped) {
|
||||
new ExpressionHider(name, scoped).visitBeanDefinition(definition);
|
||||
if (!isSpringThree()) {
|
||||
new ExpressionHider(name, scoped).visitBeanDefinition(definition);
|
||||
}
|
||||
createScopedProxy(beanName, definition, registry, proxyTargetClass);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static boolean isSpringThree() {
|
||||
return ReflectionUtils.findMethod(Scope.class, "resolveContextualObject", new Class<?>[] { String.class }) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the name property. This can then be used as a bean
|
||||
* definition attribute, e.g. scope="step". Defaults to "step".
|
||||
@@ -249,10 +264,19 @@ public class StepScope implements Scope, BeanFactoryPostProcessor, Ordered {
|
||||
// TODO: (for Batch 2.1) detect presence of Spring 3.0 and use
|
||||
// ScopedProxyUtils instead
|
||||
|
||||
// Create the scoped proxy...
|
||||
BeanDefinitionHolder proxyHolder = PlaceholderProxyFactoryBean.createScopedProxy(new BeanDefinitionHolder(
|
||||
definition, beanName), registry, proxyTargetClass);
|
||||
// ...and register it under the original target name
|
||||
BeanDefinitionHolder proxyHolder;
|
||||
|
||||
if (isSpringThree()) {
|
||||
proxyHolder = ScopedProxyUtils.createScopedProxy(new BeanDefinitionHolder(definition, beanName), registry,
|
||||
proxyTargetClass);
|
||||
}
|
||||
else {
|
||||
|
||||
// Create the scoped proxy...
|
||||
proxyHolder = PlaceholderProxyFactoryBean.createScopedProxy(new BeanDefinitionHolder(definition, beanName),
|
||||
registry, proxyTargetClass);
|
||||
// ...and register it under the original target name
|
||||
}
|
||||
registry.registerBeanDefinition(beanName, proxyHolder.getBeanDefinition());
|
||||
|
||||
return proxyHolder;
|
||||
@@ -310,7 +334,7 @@ public class StepScope implements Scope, BeanFactoryPostProcessor, Ordered {
|
||||
if (scopeChangeRequiresProxy) {
|
||||
// Exit here so that nested inner bean definitions are not
|
||||
// analysed
|
||||
return createScopedProxy(beanName, definition, registry, proxyTargetClass);
|
||||
return createScopedProxy(beanName, definition, registry, proxyTargetClass);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,7 +392,8 @@ public class StepScope implements Scope, BeanFactoryPostProcessor, Ordered {
|
||||
String otherScope = definition.getScope();
|
||||
boolean scopeChange = !scope.equals(otherScope);
|
||||
if (scopeChange) {
|
||||
new ExpressionHider(otherScope==null?scope:otherScope, !scoped).visitBeanDefinition(definition);
|
||||
new ExpressionHider(otherScope == null ? scope : otherScope, !scoped)
|
||||
.visitBeanDefinition(definition);
|
||||
// Exit here so that nested inner bean definitions are not
|
||||
// analysed by both visitors
|
||||
return value;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/batch"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
<beans xmlns:batch="http://www.springframework.org/schema/batch"
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/batch
|
||||
http://www.springframework.org/schema/batch/spring-batch-2.1.xsd">
|
||||
|
||||
<job id="pssJob">
|
||||
<job id="pssJob" xmlns="http://www.springframework.org/schema/batch">
|
||||
<step id="step1">
|
||||
<tasklet>
|
||||
<chunk reader="reader" writer="writer" commit-interval="1"/>
|
||||
@@ -15,30 +15,30 @@
|
||||
</step>
|
||||
</job>
|
||||
|
||||
<job-repository id="jobRepository"/>
|
||||
<batch:job-repository id="jobRepository"/>
|
||||
|
||||
<beans:bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
|
||||
<beans:property name="jobRepository" ref="jobRepository" />
|
||||
</beans:bean>
|
||||
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
|
||||
<property name="jobRepository" ref="jobRepository" />
|
||||
</bean>
|
||||
|
||||
<beans:bean id="reader" class="org.springframework.batch.item.database.JdbcCursorItemReader">
|
||||
<beans:property name="sql" value="select ID, NAME, VALUE from FOO where ID >= ? and ID <= ?"/>
|
||||
<beans:property name="preparedStatementSetter" ref="pss"/>
|
||||
<beans:property name="dataSource" ref="dataSource"/>
|
||||
<beans:property name="rowMapper">
|
||||
<beans:bean class="org.springframework.batch.core.resource.FooRowMapper"/>
|
||||
</beans:property>
|
||||
</beans:bean>
|
||||
<bean id="reader" class="org.springframework.batch.item.database.JdbcCursorItemReader">
|
||||
<property name="sql" value="select ID, NAME, VALUE from FOO where ID >= ? and ID <= ?"/>
|
||||
<property name="preparedStatementSetter" ref="pss"/>
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="rowMapper">
|
||||
<bean class="org.springframework.batch.core.resource.FooRowMapper"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<beans:bean id="pss" class="org.springframework.batch.core.resource.ListPreparedStatementSetter" scope="step">
|
||||
<beans:property name="parameters">
|
||||
<beans:list>
|
||||
<beans:value>#{jobParameters[min.id]}</beans:value>
|
||||
<beans:value>#{jobParameters[max.id]}</beans:value>
|
||||
</beans:list>
|
||||
</beans:property>
|
||||
</beans:bean>
|
||||
<bean id="pss" class="org.springframework.batch.core.resource.ListPreparedStatementSetter" scope="step">
|
||||
<property name="parameters">
|
||||
<list>
|
||||
<value>#{jobParameters['min.id']}</value>
|
||||
<value>#{jobParameters['max.id']}</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<beans:bean id="writer" class="org.springframework.batch.core.resource.ListPreparedStatementSetterTests$FooStoringItemWriter"/>
|
||||
<bean id="writer" class="org.springframework.batch.core.resource.ListPreparedStatementSetterTests$FooStoringItemWriter"/>
|
||||
|
||||
</beans:beans>
|
||||
</beans>
|
||||
Reference in New Issue
Block a user