spring 源码阅读
IOC容器 实现
-
AliasRegistry
interface
提供别名注册的能力 实现有
- SimpleAliasRegistry 使用ConcurrentHashMap实现别名注册
-
BeanDefinitionRegistry
interface
提供了BeanDefinition注册的能力,实现有
- SimpleBeanDefinitionRegistry 使用ConcurrentHashMap实现,同时这个类继承SimpleAliasRegistry 提供别名和beanDefinition注册的双重能力
- DefaultListableBeanFactory //TODO 后面详细介绍
-
SingletonBeanRegistry
interface
提供单例对象注册的能力 实现有
-
DefaultSingletonBeanRegistry
这个类还继承了 SimpleAliasRegistry,拥有别名注册的能力,
实现比较复杂!! -
FactoryBeanRegistrySupport
提供和 工厂bean创建的对象 cache支持
- ConfigurableBeanFactory
interface
//TODO 后面介绍
-
-
BeanFactory
interface
提供spring ioc 容器的基本功能,包含bean的获取、别名的获取、bean是否存在的判断等等...
- HierarchicalBeanFactory
interface
BeanFactory的扩展,提供parentBeanFactory的支持,更大范围搜索:
- ListableBeanFactory
interface
提供了很多bean、beanName、beanDefinition的获取手段
- AutowireCapableBeanFactory
interface
提供bean创建、bean注入、bean销毁、属性注入、BeanPostProcessor调用等等等功能
- ConfigurableBeanFactory
interface
提供BeanFactory 配置功能
- ConfigurableListableBeanFactory
interface
提供 额外的更多的 配置项
- AbstractBeanFactory
从IOC容器类uml图看,该类 的功能比较少,没有注入功能,没有beanDefinition注册功能等等
- AbstractAutowireCapableBeanFactory
扩展AbstractBeanFactory, 提供了bean注入功能
- DefaultListableBeanFactory
BeanFactory的完全体,提供单例注册,别名注册,beanDefinition注册,BeanFactory等等功能
- XmlBeanFactory
DefaultListableBeanFactory 的一个实现,主要实现读取Xml配置,注册BeanDefinition的功能
- HierarchicalBeanFactory
XmlBeanFactory 解析
- 简单使用
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class XmlBeanFactoryTest {
public static void main(String[] args) {
Resource resource = new ClassPathResource("application.xml");
XmlBeanFactory beanFactory = new XmlBeanFactory(resource);
User user = beanFactory.getBean(User.class);
System.out.println(user);
}
}
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.joecqupt.beanfactory.User">
<property name="name" value="joe"/>
<property name="age" value="24"/>
</bean>
</beans>
import lombok.Data;
@Data
public class User {
private String name;
private int age;
}
-
源码解析
- XmlBeanFactory 使用 XmlBeanDefinitionReader读取Xml配置信息
- XmlBeanBeanDefinitionReader 构造函数需要一个 BeanDefinitionRegistry对象,因为它会将读取的配置注册进去,XmlBeanFactory刚好实现了BeanDefinitionRegistry接口
- XmlBeanDefinitionReader 会将配置文件xml解析成 Document对象,然后借助XmlBeanDefinitionDocumentReader SAX解析将Document解析成BeanDefinition
- XmlBeanDefinitionDocumentReader会委托 BeanDefinitionParserDelegate代理解析 Element 为 BeanDefinition
- BeanDefinitionParserDelegate 根据namespace来解析ELement,如果是默认的namespace使用delegate解析,如果是其他的namespace则使用 对用的XXXNameSpaceHandler对Element进行解析
- 解析Bean Element(主要讲一下property的解析方式) 会将property属性解析为PropertyValue,添加到BeanDefinition对象的propertyValues列表中去。
-
BeanDefinition代码继承关系
-
AttributeAccessor
interface
提供属性操作能力
-
BeanMetadataElement
interface
提供获取当前配置获取的 Element信息
-
BeanDefinition
interface
提供了BeanDefinition各种配置项目
-
AttributeAccessorSupport
提供属性操作能力实现,内部使用map存储属性,对属性的操作映射到对此map的操作
-
BeanMetadataAttributeAccessor
提供了BeanMetadataAttribute的注册和获取能力
-
AbstractBeanDefinition
提供了BeanDefinition更多的配置项
-
GenericBeanDefinition
提供了parentName的设置
NamespaceHander
默认的namespace(
spring 借助 NamespaceHandlerResolver 和 NamespaceHandler 两个接口来实现, NamespaceHandlerResolver 会默认加载所有jar包的 META-INF/spring.handlers 的配置,然后获取到目前支持的 namespace-namespceHandler的映射。
NamespaceHandler中的init方法会 注册该namespace下 elementName - BeanDefinitionParser的映射
在XmlBeanFactory中获取bean
在以前的工作中,xmlBeanFactory做的工作只是将xml文件的配置转化为了BeanDefinition注册到了XmlBeanFactory中去。
通过getBean()方法可以从BeanFactory中获取 Bean的实例
源码解析getBean(beanName)
- 实现的类在AbstractBeanFactory,首先回去尝试加载一下 已经成功加载的单例bena缓存中获取一下当前beanName是否存在
- 如果获取不到,表明此bean没有被加载过
- 如果获取到了 // todo
- 如果parentBeanFactory不为空,然后尝试去 parentBeanFactory中去获取一下
- 这才开始真正的bean加载过程了。
- 首先 标记这个bean已经创建 在 alreadyCreated 中添加此beanName
- 然后 同时移除 mergedBeanDefinitions 中的该bean的RootBeanDefinition
因为要去创建bean,所以要重新去merge一次beanDefinition
- 开始merge BeanDefinition (会将读取xml配置获取到的GenericBeanDefinition 转换成 RootBeanDefinition)
- merge之后出口 depend-on属性,递归时初始化 depend-on的bean,同时检查循环 depend-on
- 开始去 缓存拿一下beanName对应的单例,如果没有拿到,那就去执行真正的创建bean的操作
- 开始处理BeanDefinition的 methodOverrides 配置
- 开始处理 BeanDefinition的 InstantiationAwareBeanPostProcessor 处理器 ,这个处理器能在真正去创建bean之前返回bean实例, (Aop就是通过这种方式来实现的) //todo
1. 会调用 InstantiationAwareBeanPostProcessor处理器的postProcessBeforeInstantiation 方法
2. 如果 前一个处理方法获取到了对象,那么会调用所有的BeanPostProcessor 的
postProcessAfterInitialization 方法
ps 一个是 before实例化方法 一个是after初始化方法,仔细理解一下这个意思,bean的生命周期应该是:
实例化 --> 初始化
-
开始去创建实例,首先先去 factoryBean实例缓存中 获取一下,该实例是否存在?(其实据我理解这个缓存中放的就是实例化好的对象,但是还没进行属性注入),如果获取到了就不用去实例化bean,如果没有获取到就要去实例化bean!!
-
实例化bean
- 通过提供Supplier 方法进行实例化
- 通过提供的 工厂方法实例化
- 通过某种策略来选择构造器进行Bean实例化 // todo 很复杂 下来了解
- 如果有设置SmartInstantiationAwareBeanPostProcessor,这个处理器可覆盖方法来决定使用哪一个构造器
- 实例化的过程,如果有设置 MethodOverrides 则使用过CGlib实例化,如果没有则使用反射的方式实例化
只要记得这一步的结果就是会得到一个Bean的实例,这个bean实例会装进BeanWrapper实例中
BeanWrapper 继承结构
-
PropertyEditorRegistry
提供注册PropertyEditor的能力,
PropertyEditor属性编辑类:提供属性获取、属性设置和属性变更监听器的功能
-
PropertyAccessor
提供属性操作能力
TypeDescriptor 类型描述类,提供该类型的全方位描述(包含该类型的Class和注解等)
-
TypeConverter
类型转换的能力
-
ConfigurablePropertyAccessor
提供设置和获取 ConversionService 的能力 ,ConversionService 是自从spring3.0以来提供的类型转换工具
-
BeanWrapper
提供 设置和获取被包装实例的方法,提供设置和获取PropertyDescriptor的方法;
PropertyDescriptor属性描述类:提供获取 当前属性的class,当前属性的 get、set方法等功能
-
PropertyEditorRegistrySupport
可以设置默认的一些 PropertyEditor
-
TypeConverterSupport
使用TypeConverterDelegate类进行 类型装换 // 还是有点复杂的
-
AbstractPropertyAccessor
主要是实现了 PropertyAccessor 接口的方法,实现对属性的设置功能
-
AbstractNestablePropertyAccessor
nestable 可嵌套的
-
BeanWrapperImpl
以上功能集大成者
-
bean实例化之后 如果bean是单例类型并允许循环依赖,那么去 注册一个用于早期暴露的 beanFactory,
- 这个beanFactory返回的是bean实例就是刚刚实例化后的对象(此时各个属性值还没有设置),
- 如果有设置 SmartInstantiationAwareBeanPostProcessor 处理器,那么这个BeanFactory会返回处理器处理后的 bean实例 (AOP有实现这个处理器)
-
开始给bean设置属性值
-
执行 实例化后处理器 InstantiationAwareBeanPostProcessor postProcessAfterInstantiation方法
-
执行属性处理方法 InstantiationAwareBeanPostProcessor postProcessProperties方法和postProcessPropertyValues方法
(@AutoWired @Resource 等功能就是这里处理的) -
执行 属性值 解析器:是把 XML属性设置的格式 解析出来 (比如属性可以设置 ref list map 等等格式)
-
转化器工作: 这里回去做转换,去看看setter需要什么类型,就把属性值转换成某种类型
-
通过自省去给bean实例设置 属性值 (注意这里有嵌套 属性值得设置处理 )
-
-
执行初始化
- 执行一些 *Aware接口的信息注入
- 执行处理器 postProcessBeforeInitialization 方法
- 执行InitializingBean接口 指定的方法 afterPerprotiesSet() 或者 执行自定义的 init 方法
- 执行postProcessAfterInitialization 方法
- 自此bean的实例化初始化全部完成了
-
注册bean销毁处理器
-
从创建好的bean中获取bean实例,主要是对FactoryBean进行处理,需要调用getObejct方法
-
从IOC容器中返回bean完成
ApplicationContext
继承结构如图,BeanFactory 那一段可以不用看了,看看新的这些接口
-
MessageSource
一个支持国际化的信息(message)处理器
-
EnvironmentCapable
环境感知接口,能够获取到当前 Environment 环境对象
-
ApplicationEventPublisher
事件发布器
-
ResourceLoader
资源加载器, 只有两个方法,获取ClassLoader对象 和 获取Resource对象
-
ResourcePatternResolver
资源加载器的扩展, 提供 获取Resource[] 数组的能力
-
Lifecycle
提供声明周期支持, 提供生命周期控制,只提供3个方法 start() stop() isRunning()
-
ConfigurableApplicationContext
提供application的配置功能,它新增的方法如下:
Spring MVC 加载流程
-
ContextLoaderListener
继承自ServletContextListener, 会在context创建和销毁的过程中,会自动调用 contextInitialized() contextDestroyed()
-
contextInitialized()
开始去创建 WebApplicationContext ,WebApplicationContext继承层次如下:
-