XmlWebApplicationContext加载bean XML源码解析
发布时间:2020-12-16 09:44:16 所属栏目:百科 来源:网络整理
导读:XmlWebApplicationContext是我们开发中用到的最多的ApplicationContext实现,我对其源代码详细的分析,以便以后复习的时候可以参考。 public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext { /** Default config locatio
XmlWebApplicationContext是我们开发中用到的最多的ApplicationContext实现,我对其源代码详细的分析,以便以后复习的时候可以参考。
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}; } } } 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);
//根据XML文件的bean信息加载bean属性
int loadCount = loadBeanDefinitions(resource); if (logger.isDebugEnabled()) { logger.debug( " Loaded " + loadCount + " bean definitions from location [ " + location + " ] " ); } return loadCount; } } 这儿,public int loadBeanDefinitions(Resource resource)方法是在其子类XmlBeanDefinitionReader中实现的:
//把XML中bean的配置信息注册到BeanDefinition中去
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); }
//从根节点开始读取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); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |