spring源码阅读(二)

容器的基本实现

首先查看小例子:
项目结构:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>learn</groupId>
	<artifactId>spring-resource</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<description>spring 源码阅读</description>
	<dependencies>
	
			<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
			<dependency>
				<groupId>org.springframework</groupId>
				<artifactId>spring-context</artifactId>
				<version>4.2.6.RELEASE</version>
			</dependency>


	</dependencies>
</project>
public class TestBean01 {
	public String getHello() {
		return "hello spring";
	}
}
@SuppressWarnings("deprecation")
public class BeanFactoryTest01 {
	public static void main(String[] args) {
		BeanFactory bf = new XmlBeanFactory(new ClassPathResource("BeanFactoryTest01.xml"));
		TestBean01 test=(TestBean01) bf.getBean("testBean");
		System.out.println(test.getHello());
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
	<!-- 配置需要被Spring管理的Bean(创建,创建后放在了Spring IOC容器里面) -->
	<bean id="testBean" class="char02.TestBean01"></bean>
</beans>  

现在 BeanFactory 已经很少使用了而是使用 ApplicationContext

功能分析:

  1. 首先读取配置文件
  2. 实例化读到的类
  3. 调用类的方法

ConfigReader 用于读取已经验证配置文件。
Reflection 用于反射实例化。
源码分析
首先是beans 的依赖:

UML图:

DefaultListableBeanFactory
XmlBeanFactory 继承自DefaultListableBeanFactory。而DefaultListableBeanFactory是整个bean加载的核心部分。是Spring中注册以及加载bean的默认实现。而XmlBeanFactory 与DefaultListableBeanFactory 的区别是XmlBeanFactory实现了自定义的一个xml文件读取器 XmlBeanDefinitionReader实现了个性化的BeanDefinitionReader 读取。下面是ConfigurableListableBeanFactory的层级结构图。

此图包含实现的接口:

先了解一下各个类的用法:

  • AliasRegistry:定义对alias的简单增删改等操作
  • SimpleAliasRegistry: 只要使用map作为alias的缓存并对AliasRegistry进行实现
  • SingletonBeanRegistry:定义对单例的注册以及获取。
  • BeanFactory:定义获取bean以及bean的各种属性。
  • DefaultSingletonBeanRegistry:对接口SingletonBeanRegistry的各个方法的实现。
  • HierarchicalBeanFactory:继承BeanFactory,也就是在BeanFactory的定义的功能的基础上增加对parentFactory的支持。
  • BeanDefinitionRegistry: 定义对BeanDefinition的各种增删改操作。
  • FactoryBeanRegistrySupport:在DefaultSingletonBeanRegistry基础上增加了对FactoryBean(?)的特殊处理。
  • ConfigurableBeanFactory:提供配置Factory的各种方法
  • ListableBeanFactory:根据各种条件获取bean的配置清单
  • AbstractBeanFactory:综合FactoryBeanRegistrySupport和ConfigurableBeanFactory 的功能
  • AutowireCapableBeanFactory:提供创建bean、自动注入、初始化、已经应用bean的后处理器
  • AbstractAutowireCapableBeanFactory:综合AbstractBeanFactory并对AutowireCapableBeanFactory进行实现。
  • ConfigurableListableBeanFactory:BeanFactory配置清单、指定忽略类型及接口
  • DefaultListableBeanFactory:综合以上所有功能,只要是对bean注册后的处理。

XmlBeanFactory 是对DefaultListableBeanFactory的拓展主要是从Xml中读取BeanDefinitionReader
BeanDefinitionReader 接口层次:

BeanDefinitionReader

xml配置文件的读取是spring中的一个重要的功能。那么XmlBeanDefinitionReader 梳理一下资源文件读取、解析已经注册的大致脉络。
首先肯看各个类的功能:

  • ResourceLoader: 定义资源加载器,主要是对给定资源地址返回相应的Resource
  • BeanDefinitionReader:主要定义资源读取并装换为BeanDefinition的各个功能。
  • EnvironmentCapable :定义获取Environment 的方法。
  • DocumentLoader: 定义从资源文件加载到转换成Document的方法
  • AbstractBeanDefinitionReader:对EnvironmentCapable、BeanDefinitionReader类定义功能的实现。
  • BeanDefinitionDocumentReader:定义读取Document并注册BeanDefinition 功能
  • BeanDefinitionParserDelegate: 定义解析各个Element的各种方法。
  • XmlBeanDefinitionReader:的结构层次图:
  • XmlBeanDefinitionReader 运行流程:
  1. 通过继承的AbstractBeanDefinitionReader中的ResouceLoader 将资源转换成Resouce
  2. DocumentLoader 对Resouce文件进行装换,转换成Document
  3. 通过BeanDefinitionDocumentReader对Document进行解析,并使用BeanDefinitionParserDelegate对Element进行解析。

看到这里我相信很多人都懵逼

**接下来细讲 例子中代码的详细实现功能 **

  • 配置文件的封装
    配置文件是通过 ClassPathResource进行封装的。ClassPathResouce完成了一个什么样的功能呢?
    spring定义了自己的Resource接口来封装底层资源。
  • Resoucre 的结构层次:
  • InputStreamResource:
  • Resource:
  • AbstractResource:

    此类提供了Resouce定义的一些方法的实现:
  • 然后直接看待 ClassPathResource :
    对应代码举例子中的 初始化一个Resouce:new ClassPathResource("BeanFactoryTest01.xml") 查看它做了哪些操作:

现在已经构建好了一个Resouce
继续查看XmlBeanFactory的代码的定义:

查看加载配置的实现:

这里还可以看见日志的打印:和控制台输出的对应。 在加载配置文件时候 Resource被装换成了 EncodedResource
加载配置类的实现:

其中从ClassPathResource获取InputStream的实现:

posted @ 2017-05-10 12:36  风中小蘑菇  阅读(223)  评论(0编辑  收藏  举报