【第二章】容器的基本实现

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);
    }

猜你喜欢

转载自blog.csdn.net/qq_23603437/article/details/81630225