《Spring源码深度解析》_ByteX的博客-CSDN博客
1.容器的基本实现
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
Hello hello = (Hello)beanFactory.getBean("hello");
xml配置:
<bean id="hello" class="Hello"></bean>
2.核心类介绍 XmlBeanFactory:读取资源+注册管理bean
DefaultListableBeanFactory
XmlBeanFactory继承自DefaultListableBeanFactory,而DefaultListableBeanFactory是整个Bean加载的核心部分,是Spring注册以及加载bean的默认实现,
XmlBeanDefinitionReader
XML配置文件的读取是Spring中重要的功能,因为Spring的大部分功能都是以配置文件作为切入点的XmlBeanDefinitionReader的主要功能就是资源文件读取、解析以及注册。
3.bean标签的解析以及注册
1.创建用于属性承载的BeanDefinition
2.解析各种属性:scope(singleton/prototype),lazy-init,autowire,denpends-on,primary,init-method,destory-method
子元素:replaced-method,constructor-arg,property,qualifier(通过Qualifier指定注入Bean的名称)
XML文档到GenericBeanDefinition的转换,大部分通用属性都保存在了AbstractBeanDefinition中
3.注册BeanDefinition(BeanDefinitionReaderUtils.registryBeanDefinition),使用beanName作为key,将beanDefinition放入map,别名注册
4.alisa/import/自定义标签的解析
4.bean的加载:
1.转换对应的beanName
2.尝试从缓存加载单例
3.bean的实例化
4.原型模式的依赖检查
5.检测parentBeanFactory
6.将储存XML配置文件的GenericBeanDefinition转换为RootBeanDefinition
7.寻找依赖
8.针对不同的scope进行bean的创建,在Spring中存在不同的scope
9.类型转换
protected < T> T doGetBean(final String beanName,final Class< T> requireType,final Object [] args,boolean typeCheckOnly) throws BeanException
// 提取对应的beanName
// 检查缓存中或者实例工厂中是否有对应的实例,为什么首先使用这段代码呢,因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,Spring创建bean的原则是不等bean创建完成就会创建bean的ObjectFactory提早曝光,也就是将ObjectFactory加入到缓存中,一旦下个bean创建的时候需要依赖上一个bean则直接使用ObjectFactory
// 直接尝试从缓存或singletonFactories中的ObjectFactory中获取
// 返回对应的示例,有时候存在BeanFactory的情况并不是直接返回实例本身而是返回指定方法返回实例
// 当在单例情况下才会尝试解决循环依赖,原型模式情况下,如果存在A中有B属性,B中有A属性,那么依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖
// 如果beanDefinitionMap中也就是在所有已加载的类中不包括beanName则尝试从parentBeanFactory中检测
// 递归到BeanFactory中寻找
// 如果不是仅仅做类型检查而是创建bean,需要进行记录
// 将储存在GenericBeanDefinition转换为RootBeanDefinition,如果指定BeanName是子Bean的话同时会合并父类的相关属性
// 若存在依赖则需要递归实例化依赖的bean,并缓存依赖调用
// 实例化依赖的bean后便可以实例化mbd本身了
// singleton模式的创建
// prototype模式的创建
// 指定scope上实例化bean
// 检查需要的类型是否符合bean的实际类型
}
5.bean
1 FactoryBean的使用,通过编码的方式实例化bean
2 缓存获取单例bean
singletonObjects:用于保存BeanName和创建bean实例之间的关系,bean name --> bean instance
singletonFactories:用于保存BeanName和创建bean的工厂之间的关系,bean name --> ObjectFactory
earlySingletonObjects:也是保存BeanName和创建bean实例之间的关系,与singletonObjects不同之处是,当一个单例bean被放到这里时,那么当bean还在创建过程中,就可以通过getBean方法获取到了,其目的是用来检测循环引用的。
registeredSingleton:用于保存当前所用已注册的bean。
3 从bean的实例中获取对象
4 获取单例
5 准备创建bean
6 循环依赖
Spring如何解决循环依赖
构造器循环依赖
通过构造器注入构造的循环依赖,此依赖是无法解决的,Spring容器将每一个正在创建的bean标识符放在一个“当前创建bean池”中,此时循环依赖只能抛出BeanCurrentlyInCreationException异常。
setter循环依赖
对于setter注入方式构成的循环依赖是通过Spring容器提前暴露刚创建完成构造器注入单位完成其他步骤的bean来完成的,而且只能解决单例作用域下的bean循环依赖。通过提前暴露一个单例工厂方法,从而使其他bean能引用到该bean。
prototype范围的依赖处理
对于prototype作用域bean,Spring容器无法完成依赖注入,因为Spring容器不进行缓存prototype作用域的bean,因为无法提前暴露一个创建的bean。
7 创建bean(AbstractAutowireCapableBeanFactory)
protected Object doCreateBean(final String beanName,final RootBeanDefinition mbd,final Object[] args)
// 根据指定bean使用对应的策略创建新的实例,如:工厂模式、构造函数自动注入、简单初始化等
// 是否提早曝光:单例&允许循环依赖&当前bean是否在创建中,检测循环依赖
// 为了避免后期循环依赖,可以在bean初始化完成钱将创建实例的ObjectFactory加入工厂
// 对bean在一次依赖引用,主要应用SmartInstantiationAwareBeanPostProcessor,其中我们熟知的AOP就是在这里将advice动态织入bean中,如没有则直接返回
// 对bean属性填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始化依赖bean
// 调用初始化方法,比如init-method
// earlySingletonReference只检测到有循环依赖的情况下才不会为空
// 如果exposeObject没有在初始化方法中被改变,也就是没有增强
// 检测依赖
// 因为bean创建其所依赖的bean一定是已经创建了,actualDependentBeans不为空则表示当前bean却没有没全部创建完,也就是说存在循环依赖
// 根据scope注册bean
}
6.容器的功能扩展
1 设置配置路径
ApplicationContext bf = new ClassPathXmlApplicationContext(“beanFactoryTest.xml”);
2 扩展功能
public void refresh throw BeanException,IllegalStateException
// 准备刷新的上下文环境
// 初始化BeanFactory,并进行XML文件读取
// 对BeanFactory进行各种功能的填充
// 子类覆盖方法做额外的处理
// 激活各种BeanFactory处理器
// 注册拦截Bean创建的Bean拦截器,这里只是注册真正调用是在getBean时候
// 为上下文初始化Message源,即不同语言的消息体,国际化处理
// 初始化应用消息广播器,并放入“applicationEventMulticaster”bean中
// 留给子类来初始化其它的bean
// 在所有注册的bean中查找Listener bean,注册到消息广播器中
// 初始化剩下的单实例
// 完成刷新过程,通知声明周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
}
3 加载BeanFactory
4 功能扩展
5 BeanFactory的后处理
7.AOP
1 动态AOP使用示例
2 动态AOP自定义标签
3 创建AOP代理
4 创建AOP静态代理
8.SpringBoot体系原理
1 第一个Starter
2 探索SpringApplication启动Spring
3 Starter自动化配置原理
621

被折叠的 条评论
为什么被折叠?



