什么是Bean
In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.
简而言之,bean 是由 Spring IoC 容器实例化、组装和管理的对象。
什么是 Spring Bean 的生命周期
对于普通的 Java 对象,当 new 的时候创建对象,然后该对象就能够使用了。一旦该对象不再被使用,则由 Java 自动进行垃圾回收。
而 Spring 中的对象是 bean,bean 和普通的 Java 对象没啥大的区别,只不过 Spring 不再自己去 new 对象了,而是由 IoC 容器去帮助我们实例化对象并且管理它,我们需要哪个对象,去问 IoC 容器要即可。IoC 其实就是解决对象之间的耦合问题,Spring Bean 的生命周期完全由容器控制。
Spring Bean 的生命周期
这里我们说的 Spring Bean 的生命周期主要指的是 singleton bean。
我们也来复习下 Spring 中的 bean 的作用域有哪些?
singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。
prototype : 每次请求都会创建一个新的 bean 实例。
request : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。
session : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。
global-session: 全局 session 作用域,仅仅在基于 Portlet 的 web 应用中才有意义,Spring5 已经没有了。Portlet 是能够生成语义代码(例如:HTML)片段的小型 Java Web 插件。它们基于 portlet 容器,可以像 servlet 一样处理 HTTP 请求。但是,与 servlet 不同,每个 portlet 都有不同的会话。
我们知道对于普通的 Java 对象来说,它们的生命周期就是:
实例化(new)。
该对象不再被使用时通过垃圾回收机制进行回收。
而对于 Spring Bean 的生命周期(Bean从创建到销毁的过程)来说:
实例化 Instantiation : 通过反射机制推断构造函数进行实例化 实例工厂 静态工厂
属性赋值 Populate : 解析自动装配(DI的体现) byName byType none @Autowired
在解析的过程中可能会出现循环依赖的问题,spring已经解决了这一问题。
初始化 Initialization: 调用很多的Aware beanNameAware BeanClassLoaderAware BeanFactoryAware 必定会被调用 。调用初始化的生命周期回调。 如果bean实现了AOP 在初始化的时候会实现动态代理。
销毁 Destruction : IOC容器关闭的时候调用 销毁的生命周期的回调函数。
实例化 属性赋值 初始化都是在IOC容器创建的时候就完成了,销毁是在ioc容器关闭的时候完成。
直接给到最终的主要逻辑
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 实例化阶段
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
...
Object exposedObject = bean;
try {
// 属性赋值阶段
this.populateBean(beanName, mbd, instanceWrapper);
// 初始化阶段
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
...
}
...
}
Spring Bean 的生命周期的扩展点
Bean 自身的方法
比如构造函数、getter/setter 以及 init-method 和 destory-method 所指定的方法等,也就对应着上文说的实例化 -> 属性赋值 -> 初始化 -> 销毁四个阶段。
容器级的方法(BeanPostProcessor 一系列接口)
主要是后处理器方法,比如下图的 InstantiationAwareBeanPostProcessor、BeanPostProcessor 接口方法。这些接口的实现类是独立于 Bean 的,并且会注册到 Spring 容器中。在 Spring 容器创建任何 Bean 的时候,这些后处理器都会发生作用。