两个主要容器:
- 实现
BeanFactory
接口的简单容器系列:实现容器的最基本功能 -
ApplicationContext
:增加了许多面向框架的特性,同时对应用环境作了许多适配
文章图片
这里写图片描述 BeanFactory 接口方法:
containsBean
isSingleton
isPrototype
isTypeMatch
getType
getAliases
XmlBeanFactory
为例)编程式使用IoC容器:
ClassPathResource res = new ClassPathResource("bean.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(res);
步骤:
1. 创建IoC配置文件的抽象资源,这个抽象资源包含了
BeanDefinition
的定义信息2. 创建一个
BeanFactory
,这里使用DefaultListableBeanFactory
3. 创建一个载入
BeanDefinition
的读取器,通过一个回调配置给BeanFactory
4. 从定义好的资源位置读入配置信息,具体的解析过程由
XmlBeanDefinitionReader
来完成。IoC容器的初始化过程 Resource定位过程:
文章图片
这里写图片描述
BeanDefinition的载入和解析:
对IoC容器来说,这个载入过程,相当于把定义的
BeanDefinition
在IoC容器中转化为一个Spring内部表示的数据结构的过程,这些BeanDefinition
数据在IoC容器中通过一个HashMap
来保持和维护。文章图片
这里写图片描述 BeanDefinition在IoC容器中的注册:
在
DefaultListableBeanFactory
中实现了BeanDefinitionRegistry
的接口,这个接口的实现完成BeanDefinition
向容器的注册,就是把解析得到的BeanDefinition
设置到hashMap
中去。文章图片
这里写图片描述
IoC容器的依赖注入 什么时候注入:在用户第一次向IoC容器索要bean的时候(
lazy-init
预实例化除外)文章图片
这里写图片描述
两种实例化Java对象的方法:
- 通过
BeanUtils
,使用Java反射功能 - 通过
CGLIB
的Enhancer
类的create
方法
文章图片
这里写图片描述 Bean的生命周期:
1. Bean实例的创建
2. 为Bean实例设置属性
3. 调用Bean的初始化方法
4. 应用可以通过IoC容器使用Bean
5. 当容器关闭时,调用Bean的销毁方法
【Spring|Spring IoC】lazy-init属性和预实例化:在
refresh
初始化容器的时候去getBean
去触发依赖注入FactoryBean的实现:类似于抽象工厂模式,封装Proxy、RMI、JNDI等
BeanPostProcessor的实现:
两个方法:
postProcessBeforeInitialization
/postProcessAfterInitialization
IoC容器对Bean的初始化
- 为类型是
BeanNameAware
的Bean设置Bean的名字 - 为类型是
BeanClassLoaderAware
的Bean设置类装载器 - 为类型是
BeanFactoryAware
的Bean设置自身所在的IoC容器以供回调使用 - 对
postProcessBeforeInitialization
/postProcessAfterInitialization
的回调 - 初始化属性
init-method
的处理
//开始进行依赖注入过程,先处理autowiring的注入
if (mbd.getResolvedAutowiredMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowiredMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
//这里是对autowire注入的处理,根据Bean的名字或者type进行autowire的过程
if (mbd.getResolvedAutowiredMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
if (mbd.getResolvedAutowiredMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}