Bean的作用域
- Singleton:默认作用域,单例模式,每个容器只有一个Bean实例;
- Prototype:原型模式,每次都产生一个新的bean;
- Request:为每一个请求新建一个bean,请求结束即销毁;
- Session:同一个session会话共享一个bean;
- Global-session:所有会话共享一个bean实例;
Bean的生命周期
总体流程:
实例化 ——> 初始化 ——> 使用 ——> 销毁;
细化流程:
- 实例化Bean:通过BeanDefinition对象获取信息,实例化所有Bean;
- 设置对象属性:通过依赖注入完成对象属性设置;
- 处理Aware接口:检查对象是否实现了Aware接口,并调用相关实现类;
- BeanPostProcesseor前置处理:用户自定义Bean初始化之前的处理方法;
- InitializingBean:如果Bean实现了InitializingBean接口,执行afeterPropertiesSet()方法;
- init-method:如果配置了init_method方法,则执行初始化方法;
- BeanPostProcesseor后置处理:用户自定义Bean初始化之后的处理方法;
- 使用bean;
- DisposableBean:使用完,清理阶段如果实现了DisposableBean接口,则调用destory方法;
- destroy-method:如果配置了destroy _method方法,则执行销毁方法;
BeanFactory和ApplicationContext
- BeanFactory:只是IOC容器,懒加载,启动时不加载bean,而是第一次调用才实例化;
- ApplicationContext:Spring上下文,有spring的高级功能,继承自BeanFactory,启动时就实例化了所有bean;
BeanPostProcessor和BeanFactoryPostProcessor
- BeanFactoryPostProcessor是针对bean容器的,可以在bean实例化之前,去修改bean的属性、作用域;
- BeanPostProcessor是针对bean的,是在bean实例化之后,初始化之前去修改bean的属性,要晚于BeanFactoryPostProcessor执行;
Bean循环依赖
问题:
- 通过构造方法依赖注入产生循环依赖问题;
- 通过setter方法,且在原型模式下依赖注入产生循环依赖问题;
- 通过setter方法依赖注入产生循环依赖问题;
只有问题3在spring能被解决;
解决思路:
通过spring的二级、三级缓存解决,二级缓存存储了Bean提前暴露的引用实例,此时Bean还在创建中,二级缓存就已经解决了循环依赖的问题,而三级缓存,加入了ObjectFactory,解决了在对象实现了AOP的情况下,可以提前产生被代理的对象;