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