Spring可以看作一个大型工厂,生产和管理Spring容器中的Bean。本章主要介绍了BeanFactory 和 ApplicationContext的区别以及从Bean的生命周期入手深入学习Bean的相关概念。
Spring 官方文档对 bean 的解释是: 在 Spring 中,构成应用程序主干并由Spring IOC容器管理的对象称为bean。bean是一个由Spring IOC容器实例化、组装和管理的对象。
总结来说有三点:
1.bean是对象,一个或者多个不限定。
2.bean由Spring中的IOC容器管理。
3.我们的应用程序由一个个bean构成。
BeanFactory:是IOC容器的核心接口, 它定义了IOC的基本功能
BeanFactory是Spring 的“心脏”。它就是 SpringIOC 容器的真面目。Spring使用BeanFactory 来实例化、配置和管理 Bean。
BeanFactorty接口提供了配置框架及基本功能,但是无法支持spring的aop功能和web应用。
ApplicationContext: 应用上下文,继承了BeanFactory接口,拥有BeanFactory所有的功能,它是Spring的一个功能丰富的容器,提供了更多面向实际应用的功能。
ApplicationContext在功能上做了扩展:
(1)MessageSource, 提供国际化的消息访问
(2)资源访问,如URL和文件
(3)事件传播特性,即支持AOP特性
(4)以一种面向框架的方式工作以及对上下文进行分层和实现继承:载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。
如果说BeanFactory是Spring的心脏,那么ApplicationContext就是完整的躯体了。
1.它们都可以当做 Spring 的容器,Spring 容器是生成 Bean 实例的工厂,并管理容器中的 Bean
2.ApplicationContext除了提供上述BeanFactory所能提供的功能之外,还提供了更完整的框架功能。
3.BeanFactroy采用的是延迟加载形式来注入Bean,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化(这样,我们就不能发现一些存在的Spring的配置问题)。ApplicationContext则相反,它是在容器启动时,一次性创建了所有的Bean(在容器启动时,我们就可以发现Spring中存在的配置错误)。
4.BeanFactory主要是面对 spring 框架的基础设施,面对 spring 自己。Applicationcontex 主要面对与 spring 开发者。
5.相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。
我们可以分成四个阶段
1.Bean的实例化阶段
2.Bean的设置属性阶段
3.Bean的 初始化阶段
4.Bean的销毁阶段
1.InitializingBean的afterPropertiesSet方法
2.PostConstruct注解标注的方法
3.配置的init-method
1.preDestroy注解标注的方法
2.DisposableBean接口的destroy方法
3.配置的destroy-method
在设置属性阶段后,postProcessBeforeInitialization方法执行前,会执行很多Aware类型的接口,这种类型接口作用是加载资源到Spring容器中,Aware前面的名字就对应哪种资源,依次加载的是:
1.BeanNameAware
2.BeanClassLoaderAware
3.BeanFactoryAware
4.EnvironmentAware
5.ResourceLoaderAware
6.ApplicationEventPublisherAware
7.ApplicationContextAware
注意:BeanFactoryAware之前加载的资源都是公共的。BeanFactoryAware后面加载的资源都是ApplicationContext独有的,所以说ApplicationContext提供了更多的功能。
Bean生命周期的完整流程图如下
总结:
实例化Bean
1.Bean容器找到Spring配置文件中Bean的定义;
2.Bean容器利用java 反射机制实例化Bean;
设置属性值
3.Bean容器为实例化的Bean设置属性值;
执行Aware类型的接口
4.如果Bean实现了BeanNameAware接口,则执行setBeanName方法;
5.如果Bean实现了BeanClassLoaderAware接口,则执行setBeanClassLoader方法;
6.如果Bean实现了BeanFactoryAware接口,则执行setBeanFactory方法;
7.如果Bean实现了ApplicationContextAware接口,则执行setApplicationContext方法;
初始化阶段以及前后
8.如果加载了BeanPostProcessor相关实现类,则执行postProcessBeforeInitialization方法;
9.如果Bean定义初始化方法,则执行定义的初始化方法;
10.如果加载了BeanPostProcessor相关实现类,则执行postProcessAfterInitialization方法;
销毁:
11.当要销毁这个Bean时,如果自定义了销毁方法,则执行定义的销毁方法。
ApplicationContext 包含 BeanFactory 的所有特性,通常推荐使用前者。但是也有一些限制情形,比如移动应用内存消耗比较严苛,在那些情景中,使用更轻量级的 BeanFactory是更合理的。然而,在大多数企业级的应用中,ApplicationContext 是首选。Bean的生命周期比较复杂,建议分阶段去记忆每个阶段做了什么事情。后续还会介绍Bean的线程安全问题以及循环依赖问题,加深对Bean的理解。