1. 核心类DefaultListableBeanFactory
DefaultListableBeanFactory的类图,DefaultListableBeanFactory是整个bean注册加载的默认实现,整个bean加载的核心部分,XmlBeanFactory继承了DefaultListableBeanFactory,实现了通过xml加载。
2.容器的基础XmlBeanFactory
2.1加载配置文件并封装
//spring将内部使用的资源文件实现了自己的抽象结构,Resource接口来封装底层资源
public interface InputStreamSource {
InputStream getInputStream() throws IOException;
}
public interface Resource extends InputStreamSource {
boolean exists();
boolean isReadable();
boolean isOpen();
URL getURL() throws IOException;
URI getURI() throws IOException;
File getFile() throws IOException;
long contentLength() throws IOException;
long lastModified() throws IOException;
Resource createRelative(String relativePath) throws IOException;
String getFilename();
String getDescription();
}
classPathResource中读取资源文件的具体方法
public InputStream getInputStream() throws IOException {
InputStream is;
if (this.clazz != null) {
is = this.clazz.getResourceAsStream(this.path);
}
else if (this.classLoader != null) {
//通过类加载器获取文件的输入流
is = this.classLoader.getResourceAsStream(this.path);
}
else {
is = ClassLoader.getSystemResourceAsStream(this.path);
}
if (is == null) {
throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");
}
return is;
}
到这里,整个配置文件都加载进来,并封装成了resource对象
2.2XmlBeanDefinitionReader读取resource
public class XmlBeanFactory extends DefaultListableBeanFactory {
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
}
上面代码中的this.reader.loadBeanDefinitions(resource);就是在真正加载资源了,重点分析之一,同时还可以发现在这行代码之前,还调用了父类构造器,跟踪代码到AbstractAutowireCapableBeanFactory中:
public AbstractAutowireCapableBeanFactory() {
super();
/**
* ignoreDependencyInterface的主要功能是忽略给定接口的自动装配功能,
* 目的是:实现了BeanNameAware接口的属性,不会被Spring自动初始化。
*
*/
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
}
2.2.1loadBeanDefinitions(resource)方法时序图
这个方法做的事实际上是准备数据的过程,真正加载bean的是最后return的doLoadBeanDefinitions(inputSource, encodedResource.getResource())方法
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource){
/**
* 还有一步,验证xml格式,4.x放在了此方法内
* 加载xml文件并得到对应的Document对象
*/
Document doc = doLoadDocument(inputSource, resource);
/**
* 根据返回的doc对象获取bean的注册信息
*/
return registerBeanDefinitions(doc, resource);
}