代码:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//这里使用了委派设计模式,父类定义了抽象的refreshBeanFactory()方法,具体实现调用子类容器的refreshBeanFactory()方法
//重新实例化一个DefaultListableBeanFactory,加载xml配置,生成BeanDefinitions
refreshBeanFactory();
//返回刚刚实例化的DefaultListableBeanFactory
return getBeanFactory();
}
refreshBeanFactory会创建DefaultListableBeanFactory对象,然后调用loadBeanDefinitions方法
protected final void refreshBeanFactory() throws BeansException {
//如果beanFactory已经有了值,就将其清空,重新构建
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//创建DefaultListableBeanFactory对象,并赋值给beanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
//加载BeanDefinitions(基于tomcat的web.xml启动时,默认是调用XmlWebApplicationContext读取xml中配置的bean)
loadBeanDefinitions(beanFactory);
//赋值
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
getBeanFactory方法就是把刚刚赋值给beanFactory的DefaultListableBeanFactory对象返回.
public final ConfigurableListableBeanFactory getBeanFactory() {
DefaultListableBeanFactory beanFactory = this.beanFactory;
if (beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
return beanFactory;
}
接下来就是看loadBeanDefinitions方法
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 为给定的BeanFactory创建一个新的XmlBeanDefinitionReader。
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 使用此上下文的资源加载环境配置bean定义阅读器。
beanDefinitionReader.setEnvironment(getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
//允许一个子类提供自定义的读取器初始化,然后继续实际加载bean定义。
initBeanDefinitionReader(beanDefinitionReader);
//加载BeanDefinitions
loadBeanDefinitions(beanDefinitionReader);
}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
//xml配置路径
String[] configLocations = getConfigLocations();
if (configLocations != null) {
for (String configLocation : configLocations) {
//读取xml配置
reader.loadBeanDefinitions(configLocation);
}
}
}
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
return loadBeanDefinitions(location, null);
}
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException(
"Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
}
if (resourceLoader instanceof ResourcePatternResolver) {
// Resource pattern matching available. 可用的资源模式匹配。
try {
//将资源解析为Resource
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
//解析resources,加载BeanDefinitions
int count = loadBeanDefinitions(resources);
if (actualResources != null) {
Collections.addAll(actualResources, resources);
}
if (logger.isTraceEnabled()) {
logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
}
return count;
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"Could not resolve bean definition resource pattern [" + location + "]", ex);
}
}
else {
// Can only load single resources by absolute URL. 只能通过绝对URL加载单个资源。
Resource resource = resourceLoader.getResource(location);
int count = loadBeanDefinitions(resource);
if (actualResources != null) {
actualResources.add(resource);
}
if (logger.isTraceEnabled()) {
logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
}
return count;
}
}
@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int count = 0;
for (Resource resource : resources) {
//加载BeanDefinitions
count += loadBeanDefinitions(resource);
}
return count;
}
@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
//EncodedResource对资源文件的编码格式进行处理
return loadBeanDefinitions(new EncodedResource(resource));
}
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Loading XML bean definitions from " + encodedResource);
}
//通过属性来记录已经加载的资源
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
//获取输入流
try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//加载bean定义。(核心部分)
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
接下来的代码量有的大,我就不写出来了,大家想了解的话可以看看《spring源码深度解析 第2版》,里面有详细讲解。
下一章:五、BeanFactoryPostProcessor方法解析