001/* 002 * Copyright 2006-2010 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.springframework.batch.core.configuration.support; 017 018import java.util.ArrayList; 019import java.util.Arrays; 020import java.util.List; 021 022import org.springframework.beans.factory.BeanFactoryAware; 023import org.springframework.beans.factory.FactoryBean; 024import org.springframework.beans.factory.config.BeanFactoryPostProcessor; 025import org.springframework.beans.factory.config.BeanPostProcessor; 026import org.springframework.beans.factory.config.CustomEditorConfigurer; 027import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; 028import org.springframework.context.ApplicationContext; 029import org.springframework.context.ApplicationContextAware; 030import org.springframework.core.io.Resource; 031 032/** 033 * A convenient factory for creating a set of {@link ApplicationContextFactory} 034 * components from a set of {@link Resource resources}. 035 * 036 * @author Dave Syer 037 * 038 */ 039public class ClasspathXmlApplicationContextsFactoryBean implements FactoryBean<ApplicationContextFactory[]>, ApplicationContextAware { 040 041 private List<Resource> resources = new ArrayList<Resource>(); 042 043 private boolean copyConfiguration = true; 044 045 private Class<? extends BeanFactoryPostProcessor>[] beanFactoryPostProcessorClasses; 046 047 private Class<?>[] beanPostProcessorExcludeClasses; 048 049 private ApplicationContext applicationContext; 050 051 /** 052 * A set of resources to load using a 053 * {@link GenericApplicationContextFactory}. Each resource should be a 054 * Spring configuration file which is loaded into an application context 055 * whose parent is the current context. In a configuration file the 056 * resources can be given as a pattern (e.g. 057 * <code>classpath*:/config/*-context.xml</code>). 058 * 059 * @param resources array of resources to use 060 */ 061 public void setResources(Resource[] resources) { 062 this.resources = Arrays.asList(resources); 063 } 064 065 /** 066 * Flag to indicate that configuration such as bean post processors and 067 * custom editors should be copied from the parent context. Defaults to 068 * true. 069 * 070 * @param copyConfiguration the flag value to set 071 */ 072 public void setCopyConfiguration(boolean copyConfiguration) { 073 this.copyConfiguration = copyConfiguration; 074 } 075 076 /** 077 * Determines which bean factory post processors (like property 078 * placeholders) should be copied from the parent context. Defaults to 079 * {@link PropertyPlaceholderConfigurer} and {@link CustomEditorConfigurer}. 080 * 081 * @param beanFactoryPostProcessorClasses post processor types to be copied 082 */ 083 084 public void setBeanFactoryPostProcessorClasses( 085 Class<? extends BeanFactoryPostProcessor>[] beanFactoryPostProcessorClasses) { 086 this.beanFactoryPostProcessorClasses = beanFactoryPostProcessorClasses; 087 } 088 089 /** 090 * Determines by exclusion which bean post processors should be copied from 091 * the parent context. Defaults to {@link BeanFactoryAware} (so any post 092 * processors that have a reference to the parent bean factory are not 093 * copied into the child). Note that these classes do not themselves have to 094 * be {@link BeanPostProcessor} implementations or sub-interfaces. 095 * 096 * @param beanPostProcessorExcludeClasses the classes to set 097 */ 098 public void setBeanPostProcessorExcludeClasses(Class<?>[] beanPostProcessorExcludeClasses) { 099 this.beanPostProcessorExcludeClasses = beanPostProcessorExcludeClasses; 100 } 101 102 /** 103 * Create an {@link ApplicationContextFactory} from each resource provided 104 * in {@link #setResources(Resource[])}. 105 * 106 * @return an array of {@link ApplicationContextFactory} 107 * @see org.springframework.beans.factory.FactoryBean#getObject() 108 */ 109 @Override 110 public ApplicationContextFactory[] getObject() throws Exception { 111 112 if (resources == null) { 113 return new ApplicationContextFactory[0]; 114 } 115 116 List<ApplicationContextFactory> applicationContextFactories = new ArrayList<>(); 117 for (Resource resource : resources) { 118 GenericApplicationContextFactory factory = new GenericApplicationContextFactory(resource); 119 factory.setCopyConfiguration(copyConfiguration); 120 if (beanFactoryPostProcessorClasses != null) { 121 factory.setBeanFactoryPostProcessorClasses(beanFactoryPostProcessorClasses); 122 } 123 if (beanPostProcessorExcludeClasses != null) { 124 factory.setBeanPostProcessorExcludeClasses(beanPostProcessorExcludeClasses); 125 } 126 factory.setApplicationContext(applicationContext); 127 applicationContextFactories.add(factory); 128 } 129 return applicationContextFactories.toArray(new ApplicationContextFactory[applicationContextFactories.size()]); 130 } 131 132 /** 133 * The type of object returned by this factory - an array of 134 * {@link ApplicationContextFactory}. 135 * 136 * @return array of {@link ApplicationContextFactory} 137 * @see FactoryBean#getObjectType() 138 */ 139 @Override 140 public Class<?> getObjectType() { 141 return ApplicationContextFactory[].class; 142 } 143 144 /** 145 * Optimization hint for bean factory. 146 * @return true 147 * @see FactoryBean#isSingleton() 148 */ 149 @Override 150 public boolean isSingleton() { 151 return true; 152 } 153 154 /** 155 * An application context that can be used as a parent context for all the 156 * factories. 157 * 158 * @param applicationContext the {@link ApplicationContext} to set 159 * @see ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) 160 */ 161 @Override 162 public void setApplicationContext(ApplicationContext applicationContext) { 163 this.applicationContext = applicationContext; 164 } 165 166}