下面是Spring IOC初始化的第二步,加载
IOC加载执行流程 BeanDefinition的载入//AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//创建XmlBeanDefinitionReader,容器使用该读取器读取Bean定义资源
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//为beanDefinitionReader 设置环境
beanDefinitionReader.setEnvironment(this.getEnvironment());
//为beanDefinitionReader设置资源加载器,AbstractXmlApplicationContext的
//父类AbstractApplicationContext继承DefaultResourceLoader,因此,容器本身也是一个资源加载器
beanDefinitionReader.setResourceLoader(this);
//为Bean读取器设置解析器
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
//当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制
initBeanDefinitionReader(beanDefinitionReader);
//载入Beandefinition
loadBeanDefinitions(beanDefinitionReader);
}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
//获取Bean定义资源的定位 ClassPathXmlApplicationContext的这个为空
Resource[] configResources = getConfigResources();
if (configResources != null) {
//Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位
//的Bean定义资源
reader.loadBeanDefinitions(configResources);
}
//上一篇构造器的第二步设置 configLocations 获取Bean的定位信息
String[] configLocations = getConfigLocations();
if (configLocations != null) {
//Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位的BeanDefinition
reader.loadBeanDefinitions(configLocations);
}
}
//AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String...)
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int counter = 0;
for (String location : locations) {
counter += loadBeanDefinitions(location);
}
return counter;
}
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
return loadBeanDefinitions(location, null);
}
public int loadBeanDefinitions(String location, @Nullable SetactualResources) throws BeanDefinitionStoreException { //获取资源加载器 defaultResourceLoader ResourceLoader resourceLoader = getResourceLoader(); if (resourceLoader == null) { throw new BeanDefinitionStoreException( "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available"); } if (resourceLoader instanceof ResourcePatternResolver) { try { //将指定位置的Bean定义资源文件解析为Spring IOC容器封装的资源 //加载多个指定位置的Bean定义资源文件 Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location); //委派调用其子类XmlBeanDefinitionReader的方法,实现加载功能 int loadCount = loadBeanDefinitions(resources); if (actualResources != null) { for (Resource resource : resources) { actualResources.add(resource); } } 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 { //将指定位置的Bean定义资源文件解析为Spring IOC容器封装的资源 //加载单个指定位置的Bean定义资源文件 Resource resource = resourceLoader.getResource(location); //委派调用其子类XmlBeanDefinitionReader的方法,实现加载功能 int loadCount = loadBeanDefinitions(resource); if (actualResources != null) { actualResources.add(resource); } if (logger.isDebugEnabled()) { logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]"); } return loadCount; } }
//XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource)
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());
}
Set currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet<>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
//将资源文件转为InputStream的IO流
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
//从InputStream中得到XML的解析源
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);
}
finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
//具体的载入
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
//将XML文件转换为document对象
document doc = doLoaddocument(inputSource, resource);
//注册BeanDefinition ioc初始化第三步
return registerBeanDefinitions(doc, resource);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (SAXParseException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
}
catch (SAXException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"XML document from " + resource + " is invalid", ex);
}
catch (ParserConfigurationException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Parser configuration exception parsing XML from " + resource, ex);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"IOException parsing XML document from " + resource, ex);
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Unexpected exception parsing XML document from " + resource, ex);
}
}
加载document
//加载document
protected document doLoaddocument(InputSource inputSource, Resource resource) throws Exception {
return this.documentLoader.loaddocument(inputSource, getEntityResolver(), this.errorHandler,
getValidationModeForResource(resource), isNamespaceAware());
}
//获取实体解析器
protected EntityResolver getEntityResolver() {
if (this.entityResolver == null) {
// Determine default EntityResolver to use.
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader != null) {
this.entityResolver = new ResourceEntityResolver(resourceLoader);
}
else {
this.entityResolver = new DelegatingEntityResolver(getBeanClassLoader());
}
}
return this.entityResolver;
}
public ResourceEntityResolver(ResourceLoader resourceLoader) {
super(resourceLoader.getClassLoader());
this.resourceLoader = resourceLoader;
}
//ResourceEntityResolver的父类构造器
public DelegatingEntityResolver(@Nullable ClassLoader classLoader) {
//dtd加载器
//".dtd"
this.dtdResolver = new BeansDtdResolver();
//schema加载器
//"meta-INF/spring.schemas"
this.schemaResolver = new PluggableSchemaResolver(classLoader);
}
//获取document
public document loaddocument(InputSource inputSource, EntityResolver entityResolver,
ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {
//创建文件解析器工厂
documentBuilderFactory factory = createdocumentBuilderFactory(validationMode, namespaceAware);
if (logger.isDebugEnabled()) {
logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]");
}
//文档解析器
documentBuilder builder = createdocumentBuilder(factory, entityResolver, errorHandler);
//解析Spring的Bean定义资源
return builder.parse(inputSource);
}



