天天看点

Spring Bean作用域与声明周期

Bean的作用域

  1. Singleton:默认作用域,单例模式,每个容器只有一个Bean实例;
  2. Prototype:原型模式,每次都产生一个新的bean;
  3. Request:为每一个请求新建一个bean,请求结束即销毁;
  4. Session:同一个session会话共享一个bean;
  5. Global-session:所有会话共享一个bean实例;

Bean的生命周期

Spring Bean作用域与声明周期

总体流程:

实例化 ——> 初始化 ——> 使用 ——> 销毁;

细化流程:

  1. 实例化Bean:通过BeanDefinition对象获取信息,实例化所有Bean;
  2. 设置对象属性:通过依赖注入完成对象属性设置;
  3. 处理Aware接口:检查对象是否实现了Aware接口,并调用相关实现类;
  4. BeanPostProcesseor前置处理:用户自定义Bean初始化之前的处理方法;
  5. InitializingBean:如果Bean实现了InitializingBean接口,执行afeterPropertiesSet()方法;
  6. init-method:如果配置了init_method方法,则执行初始化方法;
  7. BeanPostProcesseor后置处理:用户自定义Bean初始化之后的处理方法;
  8. 使用bean;
  9. DisposableBean:使用完,清理阶段如果实现了DisposableBean接口,则调用destory方法;
  10. destroy-method:如果配置了destroy _method方法,则执行销毁方法;

BeanFactory和ApplicationContext

  1. BeanFactory:只是IOC容器,懒加载,启动时不加载bean,而是第一次调用才实例化;
  2. ApplicationContext:Spring上下文,有spring的高级功能,继承自BeanFactory,启动时就实例化了所有bean;

BeanPostProcessor和BeanFactoryPostProcessor

  1. BeanFactoryPostProcessor是针对bean容器的,可以在bean实例化之前,去修改bean的属性、作用域;
  2. BeanPostProcessor是针对bean的,是在bean实例化之后,初始化之前去修改bean的属性,要晚于BeanFactoryPostProcessor执行;

Bean循环依赖

问题:

  1. 通过构造方法依赖注入产生循环依赖问题;
  2. 通过setter方法,且在原型模式下依赖注入产生循环依赖问题;
  3. 通过setter方法依赖注入产生循环依赖问题;

只有问题3在spring能被解决;

解决思路:

通过spring的二级、三级缓存解决,二级缓存存储了Bean提前暴露的引用实例,此时Bean还在创建中,二级缓存就已经解决了循环依赖的问题,而三级缓存,加入了ObjectFactory,解决了在对象实现了AOP的情况下,可以提前产生被代理的对象;