加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

XmlWebApplicationContext加载bean XML源码解析

发布时间:2020-12-15 22:45:01 所属栏目:百科 来源:网络整理
导读: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中去
documentReader.registerBeanDefinitions(doc,createReaderContext(resource));
return getBeanFactory().getBeanDefinitionCount() - countBefore;
}
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
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); } }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读