Spring Bean作用域与生命周期
作用域
singleton:单例Bean只在容器中存在一个实例,在Spring内部通过HashMap来维护单例bean的缓存
prototype:每次索取bean时都会创建一个全新的Bean
request:每次请求都会创建一个全新Bean,该类型作用于Web类型的Spring容器
session:每个会话创建一个全新Bean,该类型作用于Web类型的Spring容器
globalSession:类似于session作用域,只是其用于portlet环境的web应用。如果在非portlet环境将视为session作用域
总结:以上就是spring中bean的作用域,其中singleton,prototype属于Spring bean的基本作作用域,request,session,globalSession属于web应用环境的作用域,必须有web应用环境的支持
生命周期
// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
// 1.实例化Bean
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object exposedObject = bean;
// 2.属性赋值
this.populateBean(beanName, mbd, instanceWrapper);
// 3.初始化
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
// 4.销毁-注册回调接口
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
}
复制代码
Bean 的生命周期概括起来就是 4 个阶段:
- 实例化(Instantiation)(第1步,实例化一个bean对象)
- 属性赋值(Populate)(第2步,为bean对象设置相关属性和依赖)
- 初始化(Initialization)(第 3~7 步,步骤较多,其中第 5、6 步为初始化操作,第 3、4 步为在初始化前执行,第 7 步在初始化后执行,该阶段结束,才能被用户使用)
- 检查Aware相关接口并设置依赖
- BeanPostProcessor前置处理
- 若实现了InitializingBean接口,则调用该接口的AfterPropertiesSet()方法
- 若配置了自定义的 init-method方法,则执行该方法
- BeanPostProcessor后置处理
// AbstractAutowireCapableBeanFactory.java
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 检查Aware相关接口并设置依赖
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
this.invokeAwareMethods(beanName, bean);
}
// BeanPostProcessor前置处理
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
try {
// 若实现了InitializingBean接口,则调用该接口的AfterPropertiesSet()方法
// 若配置了自定义的 init-method方法,则执行init-method方法
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor后置处理
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
复制代码
- 销毁( 8~10步,第8步不是真正意义上的销毁(还没使用呢),而是先在使用前注册了销毁的相关调用接口,为了后面第9、10步真正销毁 bean 时再执行相应的方法 )
- 注册Destruction相关回调接口 (不是真正意义上的销毁(还没使用呢))
- 是否实现DisposableBean接口
- 是否配置自定义的destory-method (和初始化过程很像,都是检查是否实现接口和配置方法)
public void destroy() {
// 9. 若实现 DisposableBean 接口,则执行 destory()方法
if (this.invokeDisposableBean) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
((DisposableBean) this.bean).destroy();
return null;
}, this.acc);
} else {
((DisposableBean) this.bean).destroy();
}
}
}
// 10. 若配置自定义的 detory-method 方法,则执行
if (this.destroyMethod != null) {
this.invokeCustomDestroyMethod(this.destroyMethod);
} else if (this.destroyMethodName != null) {
Method methodToInvoke = this.determineDestroyMethod(this.destroyMethodName);
if (methodToInvoke != null) {
this.invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
}
}
}
复制代码