Spring IOC 内部工作机制

1 Spring内部工作机制

ApplicationContext的默认实现是AbstractApplicationContext,可以通过refresh()窥探Spring在刷新时的动作

// 初始化BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
……
	   
//调用工厂后处理器
invokeBeanFactoryPostProcessors(beanFactory);

//注册Bean后处理器
registerBeanPostProcessors(beanFactory);

//初始化消息源
initMessageSource();

//初始化应用上下文事件广播器
initApplicationEventMulticaster();

//初始化其他特殊的Bean.eg由自类实现的Bean
onRefresh();

//注册事件监听器
registerListeners();

//初始化所有单例Bean,懒加载模式的Bean除外
finishBeanFactoryInitialization(beanFactory);

// 完成刷新并发布容器刷新事件
finishRefresh();

1.初始化BeanFactory:调用refreshBeanFactory()刷新BeanFactory,之后调用getBeanFactory()获得BranFactory,这两个方法都是由具体子类实现。这一步中最重要的就是Spring将形成BeanDefinitionRegistry(Bean定义注册表),但是此时的Bean都没有被初始化

2.调用工厂后处理器:在Bean定义注册表中找出工厂后处理器(BeanFactoryPostProcessor子类)并调用对象的接口方法(postProcessBeanFactory())

3.注册Bean 后处理器:在Bean定义注册表中找出Bean 后处理器(BeanPostProcessor子类)并注册到Bean后处理器注册表中

4.初始化消息源:初始化容器的国际化消息资源

5.初始化应用上下文事件广播器

6.初始化其他特使的Bean

7.注册事件监听器,方便响应容器事件

8.初始化所有单实例Bean:初始化所有的单实例Bean并形成Bean的缓存池

9.完成并发布容器刷新事件:应用上下文事件广播器会将该事件广播到每个注册的事件监听器中。

2 Spring IOC流程图


1.ResourceLoader加载bean配置文件并使用对应的Resource表示

2.BeanDefinitionReader读取Resource表示的资源并解析,将配置的Bean表示为BeanDefinition并形成BeanDefinitionRegistry。bean注册表中的Bean是最原始的Bean即没有经过任何处理的Bean。eg符号替换

3.扫描BeanDefinitionRegistry。分为两个主要的步骤

3.1 扫描BeanDefinitionRegistry识别BeanFactoryPostProcessor子类即工厂后处理器。采用工厂后处理器对Bean进行处理,对使用占位符的<bean>标签进行解析并获得配置值即占位符替换

3.2 扫描BeanDefinitionRegistry识别PropertyEditor子类即属性编辑器并形成PropertyEditorRegistry(属性编辑器注册表)

4.从BeanDefinitionRegistry中获取加工后的BeanDefinition并调用InstantiationStrategy进行Bean实例化动作

5.BeanWrepper结合BeanDefinition以及PropertyEditorRegistry中注册的属性编辑器完成属性注入动作

6.利用注册的Bean后处理器对已经完成属性设置的Bean进行后续处理,直接装配出一个准备就绪的Bean

3 BeanDefinition

BeanDefinition是Bean定义在Spring中的内部表示。


RootBeanDefinition是最常用的实现类。它对应一般性的<bean>元素标签。由于Bean存在父子关系,所以RootBeanDefinition表示父Bean,ChildBeanDefinition表示子Bean。没有父Bean的Bean也表示为RootBeanDefinition。

一般情况下BeanDefinition只在容器启动时加载并解析,除非容器刷新或者重启否则这些信息不会发生变化。

BeanDefinition的创建主要包含两个步骤。

1.利用BeanDefinitionReader读取Resource,通过解析Xml并生成DOM对象,该步仅仅是生成<bean>标签对应的Beandefinition对象,形成的Bean是半成品,占位符在该步中并没有被替换

2.利用容器中注册的BeanFactoryPostProcessor对半成品的BeanDefinition进行处理,将占位符替换成实际值。此时的Bean是成品的Bean

4 InstantiationStrategy

实例化策略负责根据BeanDefinition对象创建一个Bean实例。


SimpleInstantiationStrategy是最常用的实例化策略。该策略利用Bean的构造函数或者工厂方法创建Bean实例

CglibSubclassingInstantiationStrategy扩展了SimpleInstantiationStrategy,为进行方法注入的Bean提供了支持。利用Cglib为Bean动态生成子类。在子类中生成方法注入的逻辑,然后利用子类创建Bean的实例

InstantiationStrategy仅仅负责Bean的实例化,相当于new的功能,不会参与Bean属性的设置。我们可以获得此时的Bean实例,但是没有办法使用,因为Bean没有被初始化,Bean的初始化需要BeanWrapper来完成

5 BeanWrapper

完成Bean属性的填充工作。实例创建完成后,通过BeanWrapper将实例包装。


PropertyAccessor接口定义了访问Bean属性的方法。eg:setPropertyValue(String,Object),setPropertyValues(PropertyValues pvs);PropertyEditorRegistry是属性编辑器注册表。从类图结构上可以看出WrapperImpl有3中身份

1.对Bean进行包装即Bean包装器,Wrapper.setWrappedInstance(Object obj)完成Bean的包装

2.实现PropertyAccessor接口,可以访问Bean的属性即属性访问器

3.实现了属性编辑器注册表接口,指定了将外部数据如何转换为Bean属性的规则

可以看出BeanWrapperImpl内部封装可两类组件:1.待处理的Bean,可以直接从BeanDefinitionRegistry获取。2.一套用于设置Bean属性的属性编辑器,从BeanDefinition中获取PropertyValue并通过属性编辑器对PropertyValue进行处理获得Bean属性值并注入

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值