实例化
1.加载配置文件
BeanDefinition Reader 组件配置文件,将每个Bean对象的所有信息存放到一个一个BeanDefinition对象当中;
2.存放到beanDefinitionMap中
将BeanDefinition存储在一个名为beanDefinitionMap的Map中;
3.执行BeanFactoryPostProcess接口实现类中的注册和修改方法
BeanFactoryPostProcess用于注册和修改
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor的postProcessBeanFactory");
// 修改演示
// BeanDefinition beanDefinition = beanFactory.getBeanDefinition("user");
// beanDefinition.setBeanClassName("com.apesource.pojo.Student");
//注册演示
BeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClassName("com.apesource.pojo.Student");
//强转成DefaultListableBeanFactory
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) beanFactory;
defaultListableBeanFactory.registerBeanDefinition("stu",beanDefinition);
}
}
BeanDefinitionRegistryPostProcessor 主要是去注册
public class MyBeanFactoryPostProcessor2 implements
BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory
configurableListableBeanFactory) throws BeansException {}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry
beanDefinitionRegistry) throws BeansException {
BeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClassName("com.apesource.pojo.Student");
beanDefinitionRegistry.registerBeanDefinition("stu",beanDefinition);
}
}
4:获取Bean信息,创建半成品Bean对象
ApplicationContext底层遍历beanDefinitionMap,创建Bean半成品实例对象(由于其还没有注入它的属性值,只是创建了对象);
初始化
1,属性赋值
Spring在进行属性注入时,会分为如下几种情况:
注入普通属性,String、int或存储基本类型的集合时,直接通过set方法的反射设置进去;
注入单向对象引用属性时,从容器中getBean获取后通过set方法反射设置进去,如果容器中没 有,则先创建被注入对象Bean实例(完成整个生命周期)后,在进行注入操作;
注入双向对象引用属性时,就比较复杂了,涉及了循环引用(循环依赖)
2,执行实现了的Aware接口中的方法
Aware接口是一种框架辅助属性注入的一种思想,其他框架中也可以看到类似的接口。框架具备高度封 装性,我们接 触到的一般都是业务代码,一个底层功能API不能轻易的获取到,但是这不意味着永远用 不到这些对象,如果用到了 ,就可以使用框架提供的类似Aware的接口,让框架给我们注入该对象 总结:处理器的作用,为Bean生命周期各个阶段提供扩展
3,执行BeanPostProcesser接口实现类的before()方法
Bean后处理器 – BeanPostProcessor Bean被实例化后,到最终缓存到名为singletonObjects单例池之前,中间会经过Bean的初始化过程, 例如:属性 的填充、初始方法init的执行等,其中有一个对外进行扩展的点BeanPostProcessor,我们称为Bean后 处理。跟上 面的 Bean工厂后处理器相,也是一个接口,实现了该接口并被容器管理的BeanPostProcessor, 会在流程节点上被Spring自动调用。
4,执行InitializingBean接口初始化方法
5,执行自定义初始化方法
6,执行BeanPostProcesser接口实现类的After()方法
//1.自定义MyBeanPostProcessor
public class MyBeanPostProcessor implements BeanPostProcessor {
/* 参数: bean是当前被实例化的Bean,beanName是当前Bean实例在容器中的名称
返回值:当前Bean实例对象 */
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("BeanPostProcessor的before方法...");
return bean;
}
/* 参数: bean是当前被实例化的Bean,beanName是当前Bean实例在容器中的名称
返回值:当前Bean实例对象 */
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("BeanPostProcessor的after方法...");
return bean;
}
}
//2.注入配置MyBeanPostProcessor
<bean class="com.apesource.processors.MyBeanPostProcessor"></bean>
getBean()调用
销毁
1,执行接口销毁方法
2,执行自定义销毁方法
Spring Bean生命周期总结:
循环依赖问题:
Bean对象A 依赖Bean对象B,同时Bean对象B依赖Bean对象A,即循环依赖
Spring解决:对Bean对象的存放设立三级缓存
Spring提供了三级缓存存储 完整Bean实例 和 半成品Bean实例 ,用于解决循环引用问题 在DefaultListableBeanFactory的上四级父类DefaultSingletonBeanRegistry中提供如下三个Map
public class DefaultSingletonBeanRegistry ... {
//1、最终存储单例Bean成品的容器,即实例化和初始化都完成的Bean,称之为"一级缓存"
Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
//2、早期Bean单例池,缓存半成品对象,且当前对象已经被其他对象引用了,称之为"二级缓存"
Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);
//3、单例Bean的工厂池,缓存半成品对象,对象未被引用,使用时在通过工厂创建Bean,称之为"三级缓存"
Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
}
注:将对象保存至三级缓存的时候,会包装成ObjectFactory对象录入,未来通过此接口对应的get方法再
次提取对象
循环依赖eg:UserService和UserDao构成循环依赖
UserService和UserDao循环依赖的过程结合上述三级缓存描述一下
UserService 实例化对象,但尚未初始化,将UserService存储到三级缓存;
UserService 属性注入,需要UserDao,从缓存中获取,没有UserDao;
UserDao实例化对象,但尚未初始化,将UserDao存储到到三级缓存;
UserDao属性注入,需要UserService,从三级缓存获取UserService,
UserService从三级缓存移 入二级缓存;
UserDao执行其他生命周期过程,最终成为一个完成Bean,存储到一级缓存,删除二三级缓存; UserService 注入UserDao; UserService执行其他生命周期过程,最终成为一个完成Bean,存储到一级缓存,删除二三级缓 存。
二.spring对于bean的作用域
含义:bean在spring容器中创建的策略以及访问的范围
位置:bean标签属性位置
语法:scope=""
属性值:
singleton========>单例模式====全局唯一====性能好====安全性低(默认方式)
prototype========>多例模式====全局不唯一====性能不好====安全性高
============================以下作用域数据web模块===============================
request========>一次请求创建一个对象
session========>一个会话创建一个对象
三.spring对于bean的生命周期管理
单例模式:
实例化=====>容器创建的时候实例化
属性赋值
初始化=====>实例化完成,则自动初始化
接口初始化:InitializingBean中的afterPropertiesSet
属性初始化:init-method属性绑定方法
使用操作
销毁======>容器关闭,单例的bean则自动销毁
接口销毁:DisposableBean
属性销毁:destroy-method="",完成资源回收