001/*
002 * Copyright 2002-2016 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 */
016
017package org.springframework.context.support;
018
019import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
020import org.springframework.core.env.ConfigurableEnvironment;
021import org.springframework.core.io.ClassPathResource;
022import org.springframework.core.io.Resource;
023
024/**
025 * Convenient application context with built-in XML support.
026 * This is a flexible alternative to {@link ClassPathXmlApplicationContext}
027 * and {@link FileSystemXmlApplicationContext}, to be configured via setters,
028 * with an eventual {@link #refresh()} call activating the context.
029 *
030 * <p>In case of multiple configuration files, bean definitions in later files
031 * will override those defined in earlier files. This can be leveraged to
032 * intentionally override certain bean definitions via an extra configuration
033 * file appended to the list.
034 *
035 * @author Juergen Hoeller
036 * @author Chris Beams
037 * @since 3.0
038 * @see #load
039 * @see XmlBeanDefinitionReader
040 * @see org.springframework.context.annotation.AnnotationConfigApplicationContext
041 */
042public class GenericXmlApplicationContext extends GenericApplicationContext {
043
044        private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
045
046
047        /**
048         * Create a new GenericXmlApplicationContext that needs to be
049         * {@link #load loaded} and then manually {@link #refresh refreshed}.
050         */
051        public GenericXmlApplicationContext() {
052        }
053
054        /**
055         * Create a new GenericXmlApplicationContext, loading bean definitions
056         * from the given resources and automatically refreshing the context.
057         * @param resources the resources to load from
058         */
059        public GenericXmlApplicationContext(Resource... resources) {
060                load(resources);
061                refresh();
062        }
063
064        /**
065         * Create a new GenericXmlApplicationContext, loading bean definitions
066         * from the given resource locations and automatically refreshing the context.
067         * @param resourceLocations the resources to load from
068         */
069        public GenericXmlApplicationContext(String... resourceLocations) {
070                load(resourceLocations);
071                refresh();
072        }
073
074        /**
075         * Create a new GenericXmlApplicationContext, loading bean definitions
076         * from the given resource locations and automatically refreshing the context.
077         * @param relativeClass class whose package will be used as a prefix when
078         * loading each specified resource name
079         * @param resourceNames relatively-qualified names of resources to load
080         */
081        public GenericXmlApplicationContext(Class<?> relativeClass, String... resourceNames) {
082                load(relativeClass, resourceNames);
083                refresh();
084        }
085
086
087        /**
088         * Exposes the underlying {@link XmlBeanDefinitionReader} for additional
089         * configuration facilities and {@code loadBeanDefinition} variations.
090         */
091        public final XmlBeanDefinitionReader getReader() {
092                return this.reader;
093        }
094
095        /**
096         * Set whether to use XML validation. Default is {@code true}.
097         */
098        public void setValidating(boolean validating) {
099                this.reader.setValidating(validating);
100        }
101
102        /**
103         * Delegates the given environment to underlying {@link XmlBeanDefinitionReader}.
104         * Should be called before any call to {@code #load}.
105         */
106        @Override
107        public void setEnvironment(ConfigurableEnvironment environment) {
108                super.setEnvironment(environment);
109                this.reader.setEnvironment(getEnvironment());
110        }
111
112
113        //---------------------------------------------------------------------
114        // Convenient methods for loading XML bean definition files
115        //---------------------------------------------------------------------
116
117        /**
118         * Load bean definitions from the given XML resources.
119         * @param resources one or more resources to load from
120         */
121        public void load(Resource... resources) {
122                this.reader.loadBeanDefinitions(resources);
123        }
124
125        /**
126         * Load bean definitions from the given XML resources.
127         * @param resourceLocations one or more resource locations to load from
128         */
129        public void load(String... resourceLocations) {
130                this.reader.loadBeanDefinitions(resourceLocations);
131        }
132
133        /**
134         * Load bean definitions from the given XML resources.
135         * @param relativeClass class whose package will be used as a prefix when
136         * loading each specified resource name
137         * @param resourceNames relatively-qualified names of resources to load
138         */
139        public void load(Class<?> relativeClass, String... resourceNames) {
140                Resource[] resources = new Resource[resourceNames.length];
141                for (int i = 0; i < resourceNames.length; i++) {
142                        resources[i] = new ClassPathResource(resourceNames[i], relativeClass);
143                }
144                this.load(resources);
145        }
146
147}