AbstractApplicationContext源码讲解
一、
AbstractApplicationContext.java ---- refresh() 方法 refresh [rɪˈfreʃ] 刷新
读取配置文件:ClassPathXmlApplicationContext 和 XmlBeanFactory 一样的作用
AbstractApplicationContext类中 refresh方法:
① prepareRefresh() 准备工作 prepareRefresh()方法中:
// 设置容器启动的时间 this.startupDate = System.currentTimeMillis(); // 容器的关闭标志位 this.closed.set(false); // 容器的激活标志位 this.active.set(true);
ⅠinitPropertySources() 初始化属性资源 -- 为了子类相关的扩展,默认情况下是空的
Ⅱ getEnvironment() .validateRequiredProperties 获取环境 验证属性资源
validate [ˈvælɪdeɪt] 验证
Environment 环境接口,包含了当前系统的某些属性值或者变量值
new StandardEnvironment()时,父类对象也要创建,父类AbstractEnvironment构造方法中,
customize [ˈkʌstəmaɪz] 定制 customizePropertySources 定制化属性资源,父类中此方法没有实现,需调用子类的实现,
所有源码中的super()方法需要看
Ⅲ
Store pre-refresh ApplicationListeners... 存储预刷新的应用监听器
applicationListeners当前为空,是为方便做扩展实现,springboot源码中,applicationListeners有值。
early [ˈɜːli]早期的
Ⅳ this.earlyApplicationEvents = new LinkeHashSet(); 指定监听器事件集合
② ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
obtain [əbˈteɪn]获得 fresh 最新的
DefaultListableBeanFactory类图(Diagram [ˈdaɪəɡræm]图解)
社区版idea不支持UML类图
hierarchical [ˌhaɪəˈrɑːkɪkl] 等级制的;层次;继承
Ⅰ HierarchicalBeanFactory : spring是单一的容器,springMVC是有父子容器,查找bean时,先在当前容器查找,找不到再到父容器查找
AbstractBeanFactory.java 中 doGetBean方法:
Ⅱ ListableBeanFactory 注释信息
由bean工厂实现的{@link BeanFactory}接口的扩展(即子接口),该bean工厂可以枚举其所有bean实例,而不是按照名字在客户端的请求逐个尝试bean查找
Extension 扩展 attempt [əˈtempt] 尝试
Ⅲ ConfigurableBeanFactory
大多数的bean工厂都实现此配置接口。为bean工厂提供配置,另外提供客户端方法(set方法)
provide [prəˈvaɪdz] 提供 facility [fəˈsɪlɪtiz] 设备、装置 addition [əˈdɪʃn] 附加
spring源码中有很多接口和抽象类,spring框架就是为了提高扩展性,比如要实现一个既能够枚举bean实例,又具有继承关系的beanfactory,就只需实现HirerarchicalBeanFactory和ListableBeanFactory接口即可
所有的东西都掺在一个类,耦合度太高
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 创建的是DefaultListableBeanFactory
refreshBeanFactory 创建一个新的工厂,开始工厂中的属性值都是默认值,下一步对属性赋值
customizeBeanFactory customize [ˈkʌstəmaɪz]定制
配置文件中有 lookup-method和replaced-method ,设置是否覆盖同名称的不同定义的对象、是否允许bean之间存在循环依赖;
circular [ˈsɜːkjələ(r)] 环形的;圆形的
AbstractRefreshApplicationContext类中 -- refreshBeanFactory()方法
loadBeanDefinitions(beanFactory) - 加载xml配置文件的属性值到当前工厂中 - 很复杂,很多重载,每次重载传入的参数不同
setConfigLocations方法是在ClassPathXmlApplicationContext类中
二、bean工厂增强器源码 AbstractApplicationContext.java refresh()方法
① prepareBeanFactory(beanFactory); ---- 完成bean工厂的某些初始化操作
class loader 类加载器 expression n. 表达式;表示 resolver[rɪˈzɒlvə] 问题解决者
expression resolver 表达式解析器
StandarBeanExpressionResolver.java 注释 standard 标准 evaluate [ɪˈvæljueɪt]估计;评估 parse 语法解析
BeanExpressionrResolver接口的标准实现,使用spring的表达式模块解析和评估spring EL表达式(#{5})
忽略对应接口的实现
Aware的接口的回调是在一个方法中: invokeAwareMethod()
resolvable 可解决的 register 注册
② postProsessBeanFactory(beanFactory) 方法内是空的,方便扩展
beanFactoryPostProcessor.java接口中 方法名字也是postProsessBeanFactory
③ invokeBeanFactoryPostProcessors(beanFactory) invoke调用
调用各种beanFactory处理器
④ 实例化之前的准备工作
registerBeanPostProcessors(beanFactory) ,
实例化并 注册beanPostProcessor
initMessageSource() --- i18n国际化处理 -- 一般用不到
initApplicationEventMulticaster() -- 初始化事件监听多路广播器
onRefresh() -- 空
registerListeners() -- 注册监听器
三、实例化
finishBeanFactoryInitialization() 实例化所有剩下的单实例(非懒加载的) --- 此方法很重要
remain [rɪˈmeɪn] 剩余
conversion [kənˈvɜːʃn] n.转换 conversion service 转换服务-- 类型转换
beanFactory中设置类型转换的操作
embed [ɪmˈbed] vt.嵌入;内置 resolution [ˌrezəˈluːʃn] n. 解析;解决
attribute 属性 resolver [rɪˈzɒlvə] 解析器 place holder 占位符
weaver 织入 freeze 冻结
beanFactory.freezeConfiguration() -- 冻结bean,说明该bean不需要修改操作了
(1) DefaultListableBeanFactory类中---- preInstantiateSingletons()方法
①RootBeanDefinition bd = getMergedLocalBeanDefinition(beanNames)
GenericBeanDefinition
merge 合并 traverse [ˈtrævɜːs]横过;穿过(遍历)
specify [ˈspesɪfaɪ]具体说明 correspond [ˌkɒrəˈspɒnd]符合;类似于
如果这个指定的bean 相当于子类bean,则遍历其父类bean,返回一个合并的bean信息
例如:<bean id="person" class="...." abstract=".."> 指定抽象类
② Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
getBean方法中 --- doGetBean方法
doGetBean 、doCreateBean、doRegisterBeanDifinition --- doXXX是实际干活的方法
doGetBean方法中:
transform [trænsˈfɔːm] 使改变;使转换
Object sharedInstance = getSingleton(beanName); --- 容器中放bean的map有三级缓存,提前检查缓存中是否已存在对象。
DefaultSingletonBeanRegistry.java中,singletonObjects是一级缓存,earlySingletonObject是二级缓存,singleFactories是三级缓存. early 早期的
③ prototype [ˈprəʊtətaɪp] 原型;----- bean类型: 每次需要的时候new
循环依赖: A 依赖 B,B依赖A
第三次缓存中的缓存类型,和第一、第二级缓存类型不同。
④ markBeanAsCreated(beanName) --- 创建标志位,标记已创建或将要创建的bean
⑤ sharedInstance = getSingleton(beanName, () -> {return createBean(beanName, mbd, args)})
getSingleton方法中,singletonFactory.getObject() 是调用了lamda表达式中createBean的方法。
createBean方法中,主要是doCreateBean方法
(2) doCreareBean
反射灵活性高,性能较低(在高次创建中显示性能低,简单少次性能不低)
special 特殊的;专用的 instantiate示例 instantiation 实例化
strategy [ˈstrætədʒi] 策略 subclass 子类
beanInstance = getInstantiationStrategy().instantiate(..);---实例化,属性值为默认值
wrapper [ˈræpə(r)]包装纸
①循环依赖 分为 构造器循环依赖,set循环依赖,构造器循环依赖没办法解决。
为什么要使用三级缓存?----- 对象需要被代理时,需要三级缓存
reference 参考;标识 exposed无保护的;风险高的; populate 填充
populateBean() --- 属性填充
②initializeBean 执行初始化逻辑
invokeAwareMethods 调用aware方法
BeanPostProessor.before --- applyBeanPostProcessorsBeforeInitialization()
执行init-method方法: invokeInitMethods
BeanPostProessor.after --- applyBeanPostProcessorsAfterInitialization()
registerDisposableBeanIfNecessary -- 注册 当bean需要销毁时要执行的方法
(3) bean = getObjectForBeanInstance(shareInstance, name, beanName, mbd) ----
getObjectFromFactoryBean ---- doGetObjectFromFactoryBean --- factory.getObject()