Make StepScope a BeanFactoryPostProcessor.
BATCH-88: StatisticsProvider is a leaky abstraction http://opensource.atlassian.com/projects/spring/browse/BATCH-88
This commit is contained in:
@@ -19,7 +19,9 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.Scope;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
|
||||
@@ -31,12 +33,14 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class StepScope implements Scope, BeanFactoryAware, BeanPostProcessor {
|
||||
public class StepScope implements Scope, BeanFactoryAware, BeanPostProcessor,
|
||||
BeanFactoryPostProcessor {
|
||||
|
||||
/**
|
||||
* Context key for clients to use for conversation identifier.
|
||||
*/
|
||||
public static final String ID_KEY = "JOB_IDENTIFIER";
|
||||
private String name = "step";
|
||||
|
||||
/**
|
||||
* Injection callback for BeanFactory. Ensures that the bean factory
|
||||
@@ -56,8 +60,9 @@ public class StepScope implements Scope, BeanFactoryAware, BeanPostProcessor {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.beans.factory.config.Scope#get(java.lang.String,
|
||||
* org.springframework.beans.factory.ObjectFactory)
|
||||
* org.springframework.beans.factory.ObjectFactory)
|
||||
*/
|
||||
public Object get(String name, ObjectFactory objectFactory) {
|
||||
SimpleStepContext context = getContext();
|
||||
@@ -71,6 +76,7 @@ public class StepScope implements Scope, BeanFactoryAware, BeanPostProcessor {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.beans.factory.config.Scope#getConversationId()
|
||||
*/
|
||||
public String getConversationId() {
|
||||
@@ -81,8 +87,9 @@ public class StepScope implements Scope, BeanFactoryAware, BeanPostProcessor {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.beans.factory.config.Scope#registerDestructionCallback(java.lang.String,
|
||||
* java.lang.Runnable)
|
||||
* java.lang.Runnable)
|
||||
*/
|
||||
public void registerDestructionCallback(String name, Runnable callback) {
|
||||
StepContext context = getContext();
|
||||
@@ -91,6 +98,7 @@ public class StepScope implements Scope, BeanFactoryAware, BeanPostProcessor {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.beans.factory.config.Scope#remove(java.lang.String)
|
||||
*/
|
||||
public Object remove(String name) {
|
||||
@@ -103,31 +111,36 @@ public class StepScope implements Scope, BeanFactoryAware, BeanPostProcessor {
|
||||
* can be used to store scoped bean instances.
|
||||
*
|
||||
* @return the current step context which we can use as a scope storage
|
||||
* medium
|
||||
* medium
|
||||
*/
|
||||
private SimpleStepContext getContext() {
|
||||
SimpleStepContext context = StepSynchronizationManager.getContext();
|
||||
if (context == null) {
|
||||
throw new IllegalStateException("No context holder available for step scope");
|
||||
throw new IllegalStateException(
|
||||
"No context holder available for step scope");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* No-op.
|
||||
*
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object,
|
||||
* java.lang.String)
|
||||
* java.lang.String)
|
||||
*/
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for {@link StepContextAware} and set context.
|
||||
*
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object,
|
||||
* java.lang.String)
|
||||
* java.lang.String)
|
||||
*/
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (bean instanceof StepContextAware) {
|
||||
SimpleStepContext context = getContext();
|
||||
((StepContextAware) bean).setStepScopeContext(context);
|
||||
@@ -135,4 +148,28 @@ public class StepScope implements Scope, BeanFactoryAware, BeanPostProcessor {
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register this scope with the enclosing BeanFactory.
|
||||
*
|
||||
* @param beanFactory
|
||||
* the BeanFactory to register with
|
||||
* @throws BeansException
|
||||
* if there is a problem.
|
||||
*/
|
||||
public void postProcessBeanFactory(
|
||||
ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
beanFactory.registerScope(name, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the name property. This can then be used as a bean
|
||||
* definition attribute, e.g. scope="step". Defaults to "step".
|
||||
*
|
||||
* @param name
|
||||
* the name to set for this scope.
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -66,6 +66,16 @@ public class StepContextAwareStepScopeTests extends TestCase {
|
||||
assertEquals(context, bean.context);
|
||||
}
|
||||
|
||||
// public void testScopedBeanWithInner() throws Exception {
|
||||
// StepSynchronizationManager.open();
|
||||
// ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("scope-tests.xml", getClass());
|
||||
// TestBean bean = ((TestBean) applicationContext.getBean("inner")).child;
|
||||
// assertNotNull(bean);
|
||||
// assertEquals("bar", bean.name);
|
||||
// StepSynchronizationManager.close();
|
||||
// assertEquals(1, list.size());
|
||||
// }
|
||||
|
||||
public static class TestBean {
|
||||
String name;
|
||||
TestBean child;
|
||||
|
||||
@@ -1,35 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
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.0.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
|
||||
<property name="scopes">
|
||||
<map>
|
||||
<!-- ideally we want the scope to be an inner bean - it's fine if it isn't a BeanFactoryPostProcessor -->
|
||||
<entry key="step" value-ref="scope"/>
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="scope" class="org.springframework.batch.execution.scope.StepScope" />
|
||||
|
||||
<bean id="bean" class="org.springframework.batch.execution.scope.StepContextAwareStepScopeTests$TestBean" scope="step" destroy-method="close">
|
||||
<property name="name" value="foo"/>
|
||||
</bean>
|
||||
|
||||
<bean id="inner" class="org.springframework.batch.execution.scope.StepContextAwareStepScopeTests$TestBean" scope="step">
|
||||
<property name="child">
|
||||
<bean class="org.springframework.batch.execution.scope.StepContextAwareStepScopeTests$TestBean" destroy-method="close"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="aware" class="org.springframework.batch.execution.scope.StepContextAwareStepScopeTests$TestBeanAware" scope="step">
|
||||
<property name="name" value="bar"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
<bean class="org.springframework.batch.execution.scope.StepScope" />
|
||||
|
||||
<bean id="bean"
|
||||
class="org.springframework.batch.execution.scope.StepContextAwareStepScopeTests$TestBean"
|
||||
scope="step" destroy-method="close">
|
||||
<property name="name" value="foo" />
|
||||
</bean>
|
||||
|
||||
<bean id="inner"
|
||||
class="org.springframework.batch.execution.scope.StepContextAwareStepScopeTests$TestBean"
|
||||
scope="step">
|
||||
<property name="child">
|
||||
<bean
|
||||
class="org.springframework.batch.execution.scope.StepContextAwareStepScopeTests$TestBean"
|
||||
destroy-method="close" scope="step">
|
||||
<property name="name" value="bar" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="name" value="foo" />
|
||||
</bean>
|
||||
|
||||
<bean id="aware"
|
||||
class="org.springframework.batch.execution.scope.StepContextAwareStepScopeTests$TestBeanAware"
|
||||
scope="step">
|
||||
<property name="name" value="bar" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -9,16 +9,9 @@
|
||||
|
||||
<import resource="data-source-context.xml" />
|
||||
<import resource="data-source-context-init.xml" />
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
|
||||
<property name="scopes">
|
||||
<map>
|
||||
<entry key="step">
|
||||
<bean class="org.springframework.batch.execution.scope.StepScope" />
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- register the step scope with the application context -->
|
||||
<bean class="org.springframework.batch.execution.scope.StepScope" />
|
||||
|
||||
<bean id="jobExecutorFacade" class="org.springframework.batch.execution.facade.SimpleJobExecutorFacade">
|
||||
<property name="jobRepository" ref="simpleJobRepository" />
|
||||
|
||||
Reference in New Issue
Block a user