Allow multiple configs (xmls, java-files, packages) to be loaded in

ApplicationContextFactory
This commit is contained in:
Thomas Bosch
2014-05-12 13:29:11 +02:00
committed by Michael Minella
parent 443cbba57f
commit cc6be985ad
4 changed files with 63 additions and 29 deletions

View File

@@ -16,11 +16,6 @@
package org.springframework.batch.core.configuration.support;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
@@ -39,6 +34,11 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.util.Assert;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* {@link ApplicationContextFactory} implementation that takes a parent context and a path to the context to create.
* When createApplicationContext method is called, the child {@link ApplicationContext} will be returned. The child
@@ -61,12 +61,12 @@ public abstract class AbstractApplicationContextFactory implements ApplicationCo
private Collection<Class<?>> beanPostProcessorExcludeClasses;
/**
* Create a factory instance with the resource specified. The resource is a Spring configuration file or java
* package containing configuration files.
* Create a factory instance with the resource specified. The resources are Spring configuration files or java
* packages containing configuration files.
*/
public AbstractApplicationContextFactory(Object... resources) {
public AbstractApplicationContextFactory(Object... resource) {
this.resources = resources;
this.resources = resource;
beanFactoryPostProcessorClasses = new ArrayList<Class<? extends BeanFactoryPostProcessor>>();
beanFactoryPostProcessorClasses.add(PropertyPlaceholderConfigurer.class);
beanFactoryPostProcessorClasses.add(PropertySourcesPlaceholderConfigurer.class);

View File

@@ -46,7 +46,7 @@ public class GenericApplicationContextFactory extends AbstractApplicationContext
* Create an application context factory for the resource specified. The resource can be an actual {@link Resource},
* in which case it will be interpreted as an XML file, or it can be a &#64;Configuration class, or a package name.
*
* @param resources a resource (XML configuration file, &#064;Configuration class or java package to scan)
* @param resources some resources (XML configuration files, &#064;Configuration classes or java packages to scan)
*/
public GenericApplicationContextFactory(Object... resources) {
super(resources);
@@ -59,13 +59,13 @@ public class GenericApplicationContextFactory extends AbstractApplicationContext
protected ConfigurableApplicationContext createApplicationContext(ConfigurableApplicationContext parent,
Object... resources) {
if (allObjectsOfType(resources, Resource.class)) {
return new ResourceXmlApplicationContext(parent, resources);
return new ResourceXmlApplicationContext(parent, resources);
}
if (allObjectsOfType(resources, Class.class)) {
return new ResourceAnnotationApplicationContext(parent, resources);
return new ResourceAnnotationApplicationContext(parent, resources);
}
if (allObjectsOfType(resources, String.class)) {
return new ResourceAnnotationApplicationContext(parent, resources);
return new ResourceAnnotationApplicationContext(parent, resources);
}
List<Class<?>> types = new ArrayList<Class<?>>();
for (Object resource : resources) {
@@ -91,7 +91,7 @@ public class GenericApplicationContextFactory extends AbstractApplicationContext
private final ConfigurableApplicationContext parent;
public ApplicationContextHelper(ConfigurableApplicationContext parent, GenericApplicationContext context,
Object... configs) {
Object... config) {
this.parent = parent;
if (parent != null) {
Assert.isTrue(parent.getBeanFactory() instanceof DefaultListableBeanFactory,
@@ -102,8 +102,8 @@ public class GenericApplicationContextFactory extends AbstractApplicationContext
parentBeanFactory = null;
}
context.setParent(parent);
context.setId(generateId(configs));
loadConfiguration(configs);
context.setId(generateId(config));
loadConfiguration(config);
prepareContext(parent, context);
}
@@ -136,21 +136,21 @@ public class GenericApplicationContextFactory extends AbstractApplicationContext
@Override
protected String generateId(Object... configs) {
Resource[] resources = Arrays.copyOfRange(configs, 0, configs.length, Resource[].class);
try {
List<String> uris = new ArrayList<String>();
for (Resource resource : resources) {
uris.add(resource.getURI().toString());
}
return StringUtils.collectionToCommaDelimitedString(uris);
}
catch (IOException e) {
return Arrays.toString(resources);
}
try {
List<String> uris = new ArrayList<String>();
for (Resource resource : resources) {
uris.add(resource.getURI().toString());
}
return StringUtils.collectionToCommaDelimitedString(uris);
}
catch (IOException e) {
return Arrays.toString(resources);
}
}
@Override
protected void loadConfiguration(Object... configs) {
Resource[] resources = Arrays.copyOfRange(configs, 0, configs.length, Resource[].class);
load(resources);
load(resources);
}
};
refresh();

View File

@@ -136,6 +136,40 @@ public class GenericApplicationContextFactoryTests {
assertEquals(other, factory);
assertEquals(other.hashCode(), factory.hashCode());
}
@Test
public void testEqualsMultileConfigs() throws Exception {
Resource resource1 = new ClassPathResource(ClassUtils.addResourcePathToPackagePath(getClass(),
"abstract-context.xml"));
Resource resource2 = new ClassPathResource(ClassUtils.addResourcePathToPackagePath(getClass(),
"child-context-with-abstract-job.xml"));
GenericApplicationContextFactory factory = new GenericApplicationContextFactory(resource1, resource2);
GenericApplicationContextFactory other = new GenericApplicationContextFactory(resource1, resource2);
assertEquals(other, factory);
assertEquals(other.hashCode(), factory.hashCode());
}
@Test
public void testParentConfigurationInheritedMultipleConfigs() {
Resource resource1 = new ClassPathResource(ClassUtils.addResourcePathToPackagePath(getClass(),
"abstract-context.xml"));
Resource resource2 = new ClassPathResource(ClassUtils.addResourcePathToPackagePath(getClass(),
"child-context-with-abstract-job.xml"));
GenericApplicationContextFactory factory = new GenericApplicationContextFactory(resource1, resource2);
ConfigurableApplicationContext context = factory.createApplicationContext();
assertEquals("concrete-job", context.getBeanNamesForType(Job.class)[0]);
assertEquals("bar", context.getBean("concrete-job", Job.class).getName());
assertEquals(4, context.getBean("foo", Foo.class).values[1], 0.01);
assertNotNull(context.getBean("concrete-job", JobSupport.class).getStep("step31"));
assertNotNull(context.getBean("concrete-job", JobSupport.class).getStep("step32"));
boolean autowiredFound = false;
for (BeanPostProcessor postProcessor : ((AbstractBeanFactory) context.getBeanFactory()).getBeanPostProcessors()) {
if (postProcessor instanceof AutowiredAnnotationBeanPostProcessor) {
autowiredFound = true;
}
}
assertTrue(autowiredFound);
}
@Test
public void testEqualsMultipleConfigs() throws Exception {

View File

@@ -21,7 +21,7 @@
<bean id="foo" class="org.springframework.batch.core.configuration.support.GenericApplicationContextFactoryTests$Foo">
<property name="values" value="1,4" />
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" value="foo=bar" />
<property name="order" value="1"/>
@@ -34,4 +34,4 @@
</map>
</property>
</bean>
</beans>
</beans>