001/*
002 * Copyright 2002-2012 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 java.io.IOException;
020
021import org.springframework.beans.BeansException;
022import org.springframework.beans.factory.support.DefaultListableBeanFactory;
023import org.springframework.beans.factory.xml.ResourceEntityResolver;
024import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
025import org.springframework.context.ApplicationContext;
026import org.springframework.core.io.Resource;
027
028/**
029 * Convenient base class for {@link org.springframework.context.ApplicationContext}
030 * implementations, drawing configuration from XML documents containing bean definitions
031 * understood by an {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader}.
032 *
033 * <p>Subclasses just have to implement the {@link #getConfigResources} and/or
034 * the {@link #getConfigLocations} method. Furthermore, they might override
035 * the {@link #getResourceByPath} hook to interpret relative paths in an
036 * environment-specific fashion, and/or {@link #getResourcePatternResolver}
037 * for extended pattern resolution.
038 *
039 * @author Rod Johnson
040 * @author Juergen Hoeller
041 * @see #getConfigResources
042 * @see #getConfigLocations
043 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
044 */
045public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {
046
047        private boolean validating = true;
048
049
050        /**
051         * Create a new AbstractXmlApplicationContext with no parent.
052         */
053        public AbstractXmlApplicationContext() {
054        }
055
056        /**
057         * Create a new AbstractXmlApplicationContext with the given parent context.
058         * @param parent the parent context
059         */
060        public AbstractXmlApplicationContext(ApplicationContext parent) {
061                super(parent);
062        }
063
064
065        /**
066         * Set whether to use XML validation. Default is {@code true}.
067         */
068        public void setValidating(boolean validating) {
069                this.validating = validating;
070        }
071
072
073        /**
074         * Loads the bean definitions via an XmlBeanDefinitionReader.
075         * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
076         * @see #initBeanDefinitionReader
077         * @see #loadBeanDefinitions
078         */
079        @Override
080        protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
081                // Create a new XmlBeanDefinitionReader for the given BeanFactory.
082                XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
083
084                // Configure the bean definition reader with this context's
085                // resource loading environment.
086                beanDefinitionReader.setEnvironment(this.getEnvironment());
087                beanDefinitionReader.setResourceLoader(this);
088                beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
089
090                // Allow a subclass to provide custom initialization of the reader,
091                // then proceed with actually loading the bean definitions.
092                initBeanDefinitionReader(beanDefinitionReader);
093                loadBeanDefinitions(beanDefinitionReader);
094        }
095
096        /**
097         * Initialize the bean definition reader used for loading the bean
098         * definitions of this context. Default implementation is empty.
099         * <p>Can be overridden in subclasses, e.g. for turning off XML validation
100         * or using a different XmlBeanDefinitionParser implementation.
101         * @param reader the bean definition reader used by this context
102         * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader#setDocumentReaderClass
103         */
104        protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
105                reader.setValidating(this.validating);
106        }
107
108        /**
109         * Load the bean definitions with the given XmlBeanDefinitionReader.
110         * <p>The lifecycle of the bean factory is handled by the {@link #refreshBeanFactory}
111         * method; hence this method is just supposed to load and/or register bean definitions.
112         * @param reader the XmlBeanDefinitionReader to use
113         * @throws BeansException in case of bean registration errors
114         * @throws IOException if the required XML document isn't found
115         * @see #refreshBeanFactory
116         * @see #getConfigLocations
117         * @see #getResources
118         * @see #getResourcePatternResolver
119         */
120        protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
121                Resource[] configResources = getConfigResources();
122                if (configResources != null) {
123                        reader.loadBeanDefinitions(configResources);
124                }
125                String[] configLocations = getConfigLocations();
126                if (configLocations != null) {
127                        reader.loadBeanDefinitions(configLocations);
128                }
129        }
130
131        /**
132         * Return an array of Resource objects, referring to the XML bean definition
133         * files that this context should be built with.
134         * <p>The default implementation returns {@code null}. Subclasses can override
135         * this to provide pre-built Resource objects rather than location Strings.
136         * @return an array of Resource objects, or {@code null} if none
137         * @see #getConfigLocations()
138         */
139        protected Resource[] getConfigResources() {
140                return null;
141        }
142
143}