From 93be098a97064958b5266c39eb0004b78b6e7954 Mon Sep 17 00:00:00 2001 From: dsyer Date: Sun, 29 Nov 2009 17:00:42 +0000 Subject: [PATCH] BATCH-1394: add support for SpEL with Spring 3.0 in step scope --- .../batch/core/scope/StepScope.java | 45 +++++++++++++---- ...stPreparedStatementSetterTests-context.xml | 50 +++++++++---------- 2 files changed, 60 insertions(+), 35 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/StepScope.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/StepScope.java index e3af71c7e..f0d6f974a 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/StepScope.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/StepScope.java @@ -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; diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/resource/ListPreparedStatementSetterTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/resource/ListPreparedStatementSetterTests-context.xml index c8dddd606..9bc494cc2 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/resource/ListPreparedStatementSetterTests-context.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/resource/ListPreparedStatementSetterTests-context.xml @@ -1,13 +1,13 @@ - - + @@ -15,30 +15,30 @@ - + - - - + + + - - - - - - - - + + + + + + + + - - - - #{jobParameters[min.id]} - #{jobParameters[max.id]} - - - + + + + #{jobParameters['min.id']} + #{jobParameters['max.id']} + + + - + - \ No newline at end of file + \ No newline at end of file