public
class
XmlWebApplicationContext
extends
AbstractRefreshableWebApplicationContext {
/** Default config location for the root context */
public static final String DEFAULT_CONFIG_LOCATION = " /WEB-INF/applicationContext.xml " ;
/** Default prefix for building a config location for a namespace */
public static final String DEFAULT_CONFIG_LOCATION_PREFIX = " /WEB-INF/ " ;
/** Default suffix for building a config location for a namespace */
public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = " .xml " ;
protected void loadBeanDefinitions(DefaultListablebeanfactory beanfactory) throws IOException {
// 创建BeanDefinitionReader,从XML中读取bean信息的读取器
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanfactory);
beanDefinitionReader.setResourceLoader( this );
beanDefinitionReader.setEntityResolver( new ResourceEntityResolver( this ));
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException,IOException {
String[] configLocations = getConfigLocations();
if (configLocations != null ) {
for ( int i = 0 ; i < configLocations.length; i ++ ) {
reader.loadBeanDefinitions(configLocations[i]);
}
}
}
protected String[] getDefaultConfigLocations() {
if (getNamespace() != null ) {
return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
}
else {
return new String[] {DEFAULT_CONFIG_LOCATION};
}
}
}
/** Default config location for the root context */
public static final String DEFAULT_CONFIG_LOCATION = " /WEB-INF/applicationContext.xml " ;
/** Default prefix for building a config location for a namespace */
public static final String DEFAULT_CONFIG_LOCATION_PREFIX = " /WEB-INF/ " ;
/** Default suffix for building a config location for a namespace */
public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = " .xml " ;
protected void loadBeanDefinitions(DefaultListablebeanfactory beanfactory) throws IOException {
// 创建BeanDefinitionReader,从XML中读取bean信息的读取器
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanfactory);
beanDefinitionReader.setResourceLoader( this );
beanDefinitionReader.setEntityResolver( new ResourceEntityResolver( this ));
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException,IOException {
String[] configLocations = getConfigLocations();
if (configLocations != null ) {
for ( int i = 0 ; i < configLocations.length; i ++ ) {
reader.loadBeanDefinitions(configLocations[i]);
}
}
}
protected String[] getDefaultConfigLocations() {
if (getNamespace() != null ) {
return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
}
else {
return new String[] {DEFAULT_CONFIG_LOCATION};
}
}
}
loadBeanDefinitions(String location)方法是在AbstractBeanDefinitionReader中实现的:
public
int
loadBeanDefinitions(String location)
throws
BeanDefinitionStoreException {
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader == null ) {
throw new BeanDefinitionStoreException(
" Cannot import bean definitions from location [ " + location + " ]: no ResourceLoader available " );
}
if (resourceLoader instanceof ResourcePatternResolver) {
// Resource pattern matching available.
try {
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
int loadCount = loadBeanDefinitions(resources);
if (logger.isDebugEnabled()) {
logger.debug( " Loaded " + loadCount + " bean definitions from location pattern [ " + location + " ] " );
}
return loadCount;
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
" Could not resolve bean definition resource pattern [ " + location + " ] " ,ex);
}
}
else {
// 根据给定的路径获得Resource.
Resource resource = resourceLoader.getResource(location);
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader == null ) {
throw new BeanDefinitionStoreException(
" Cannot import bean definitions from location [ " + location + " ]: no ResourceLoader available " );
}
if (resourceLoader instanceof ResourcePatternResolver) {
// Resource pattern matching available.
try {
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
int loadCount = loadBeanDefinitions(resources);
if (logger.isDebugEnabled()) {
logger.debug( " Loaded " + loadCount + " bean definitions from location pattern [ " + location + " ] " );
}
return loadCount;
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
" Could not resolve bean definition resource pattern [ " + location + " ] " ,ex);
}
}
else {
// 根据给定的路径获得Resource.
Resource resource = resourceLoader.getResource(location);
这儿,public int loadBeanDefinitions(Resource resource)方法是在其子类XmlBeanDefinitionReader中实现的:
//把XML中bean的配置信息注册到BeanDefinition中去
documentReader.registerBeanDefinitions(doc,createReaderContext(resource));
return getbeanfactory().getBeanDefinitionCount() - countBefore;
}
public
int
loadBeanDefinitions(Resource resource)
throws
BeanDefinitionStoreException {documentReader.registerBeanDefinitions(doc,createReaderContext(resource));
return getbeanfactory().getBeanDefinitionCount() - countBefore;
}
return loadBeanDefinitions( new EncodedResource(resource));
}
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, " EncodedResource must not be null " );
if (logger.isInfoEnabled()) {
logger.info( " Loading XML bean definitions from " + encodedResource.getResource());
}
try {
// 过的XML配置文件的输入流
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null ) {
inputSource.setEncoding(encodedResource.getEncoding());
}
return doLoadBeanDefinitions(inputSource,encodedResource.getResource());
}
finally {
inputStream.close();
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
" IOException parsing XML document from " + encodedResource.getResource(),ex);
}
}
protected int doLoadBeanDefinitions(InputSource inputSource,Resource resource)
throws BeanDefinitionStoreException {
try {
int validationMode = getValidationModeForResource(resource);
Document doc = this .documentLoader.loadDocument(
inputSource, this .entityResolver, this .errorHandler,validationMode, this .namespaceAware);
return registerBeanDefinitions(doc,resource);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (ParserConfigurationException ex) {
throw new BeanDefinitionStoreException(
" Parser configuration exception parsing XML from " + resource,ex);
}
catch (SAXParseException ex) {
throw new BeanDefinitionStoreException(
" Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid " ,ex);
}
catch (SAXException ex) {
throw new BeanDefinitionStoreException( " XML document from " + resource + " is invalid " ,ex);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException( " IOException parsing XML document from " + resource,ex);
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException( " Unexpected exception parsing XML document from " + resource,ex);
}
}
public int registerBeanDefinitions(Document doc,Resource resource) throws BeanDefinitionStoreException {
//使用 XmlBeanDefinitionParser读取配置文件,但是现在已经反对使用此类
if ( this .parserClass != null ) {
XmlBeanDefinitionParser parser =
(XmlBeanDefinitionParser) BeanUtils.instantiateClass( this .parserClass);
return parser.registerBeanDefinitions( this ,doc,resource);
}
//Spring2.0以后都用BeanDefinitionDocumentReader来读取
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getbeanfactory().getBeanDefinitionCount();
BeanDefinitionDocumentReader有一个默认的实现类DefaultBeanDefinitionDocumentReader:
public
void
registerBeanDefinitions(Document doc,XmlReaderContext readerContext) {
this .readerContext = readerContext;
logger.debug( " Loading bean definitions " );
Element root = doc.getDocumentElement();
BeanDefinitionParserDelegate delegate = createHelper(readerContext,root);
preProcessXml(root);
parseBeanDefinitions(root,delegate);
postProcessXml(root);
}
this .readerContext = readerContext;
logger.debug( " Loading bean definitions " );
Element root = doc.getDocumentElement();
BeanDefinitionParserDelegate delegate = createHelper(readerContext,root);
preProcessXml(root);
parseBeanDefinitions(root,delegate);
postProcessXml(root);
}
//从根节点开始读取bean配置信息,并把属性一一复制到BeanDefinition中去
protected void parseBeanDefinitions(Element root,BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root.getNamespaceURI())) {
NodeList nl = root.getChildNodes();
for ( int i = 0 ; i < nl.getLength(); i ++ ) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
String namespaceUri = ele.getNamespaceURI();
if (delegate.isDefaultNamespace(namespaceUri)) {
parseDefaultElement(ele,delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else { delegate.parseCustomElement(root); } }
protected void parseBeanDefinitions(Element root,BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root.getNamespaceURI())) {
NodeList nl = root.getChildNodes();
for ( int i = 0 ; i < nl.getLength(); i ++ ) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
String namespaceUri = ele.getNamespaceURI();
if (delegate.isDefaultNamespace(namespaceUri)) {
parseDefaultElement(ele,delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else { delegate.parseCustomElement(root); } }