【Spring註解】2、Bean生命週期
1、初始化和銷燬
-
通過@Bean註解的initMethod和destroyMethod屬性
-
InitializingBean介面、DisposableBean介面
-
可以使用JSR250:
-
@PostConstruct:在Bean建立完成並且屬性值完成後,執行初始化。
-
@PreDestroy:在容器銷燬Bean之前,通知進行清理工作。
-
-
使用Spring的BeanPostProcessor介面
1.1、通過@Bean註解的initMethod和destroyMethod屬性
//bean類 public class Car { public Car(){ System.out.println("car constructor..."); } public void init(){ System.out.println("car init..."); } public void destroy(){ System.out.println("car destroy..."); } }
通過@Bean註解的initMethod和destroyMethod屬性
/** * bean的生命週期: * bean建立---初始化---銷燬的過程 * * 容器管理bean的生命週期 * 我們可以自定義初始化和銷燬方法:容器在bean進行到生命週期的時候來呼叫我們自定義的初始化和銷燬方法 * * 構造: * 單例項:在容器啟動的時候建立物件 * 多例項:在每次獲取的時候建立物件 * 初始化: * 物件建立完成後,呼叫初始化方法 * 銷燬: * 單例項:容器關閉的時候 * 多例項:容器不會管理這個bean,所以容器不會呼叫銷燬方法 * * 1)、指定初始化和銷燬方法: * 通過@Bean指定init-method和destroy-method * * @author Cay * @date 2018年8月25日 下午5:18:43 */ @Configuration public class MyConfigOfLifeCycle { @Bean(initMethod="init", destroyMethod="destroy") public Car car(){ return new Car(); } }
測試:
public class TestLifeCycle {
@Test
public void test1(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfigOfLifeCycle.class);
System.out.println("容器建立完成...");
applicationContext.close();
}
}
單例項bean的初始化和銷燬測試結果:
@Bean(initMethod="init", destroyMethod="destroy") public Car car(){ return new Car(); }
@Scope("prototype")
@Bean(initMethod="init", destroyMethod="destroy")
public Car car(){
return new Car();
}
多例項bean的初始化和銷燬測試結果:
對比兩圖可以看出,單例項bean和多例項bean在初始化和銷燬時的不同。
1.2、InitializingBean介面、DisposableBean介面
通過讓Bean實現InitializingBean介面實現初始化邏輯,實現DisposableBean介面實現銷燬邏輯。
public class Cat implements InitializingBean, DisposableBean{
public Cat(){
System.out.println("cat constructor...");
}
@Override
public void destroy() throws Exception {
// TODO Auto-generated method stub
System.out.println("cat destroy...");
}
@Override
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
System.out.println("cat init...");
}
}
1.3、@PostConstruct、@PreDestroy
-
@PostConstruct:在Bean建立完成並且屬性值完成後,執行初始化。
-
@PreDestroy:在容器銷燬Bean之前,通知進行清理工作。
public class Dog {
public Dog(){
System.out.println("dog constructor...");
}
//物件建立並賦值之後呼叫
@PostConstruct
public void init(){
System.out.println("dog init...");
}
@PreDestroy
public void destroy(){
System.out.println("dog destroy...");
}
}
1.4、Spring的BeanPostProcessor介面
BeanPostProcessor是bean的後置處理器:
-
在bean初始化前後進行一些處理工作:
-
postProcessBeforeInitialization:在初始化之前
-
postProcessAfterInitialization:在初始化之後
@Component
public class MyBeanPostProcessor implements BeanPostProcessor{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessBeforeInitialization..." + beanName + "=>" + bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessAfterInitialization..." + beanName + "=>" + bean);
return bean;
}
}
BeanPostProcessor原理:
- AbstractAutowireCapableBeanFactory#configureBean
public Object configureBean(Object existingBean, String beanName) throws BeansException {
markBeanAsCreated(beanName);
BeanDefinition mbd = getMergedBeanDefinition(beanName);
RootBeanDefinition bd = null;
if (mbd instanceof RootBeanDefinition) {
RootBeanDefinition rbd = (RootBeanDefinition) mbd;
bd = (rbd.isPrototype() ? rbd : rbd.cloneBeanDefinition());
}
if (!mbd.isPrototype()) {
if (bd == null) {
bd = new RootBeanDefinition(mbd);
}
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
bd.allowCaching = ClassUtils.isCacheSafe(ClassUtils.getUserClass(existingBean), getBeanClassLoader());
}
//生成bean的包裝物件,並初始化包裝類
BeanWrapper bw = new BeanWrapperImpl(existingBean);
initBeanWrapper(bw);
//給bean進行賦值
populateBean(beanName, bd, bw);
//初始化bean
return initializeBean(beanName, existingBean, bd);
}
- AbstractAutowireCapableBeanFactory#initializeBean
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
//other...
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//呼叫applyBeanPostProcessorsBeforeInitialization方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//呼叫init方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//呼叫applyBeanPostProcessorsAfterInitialization方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
- AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
//呼叫每個BeanPostProcessor實現類的postProcessBeforeInitialization方法
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
- AbstractAutowireCapableBeanFactory#invokeInitMethods
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
//判斷bean是否實現了InitializingBean介面
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
//呼叫InitializingBean實現類的afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
return null;
}
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//呼叫InitializingBean實現類的afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
- AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//呼叫每個BeanPostProcessor實現類的postProcessAfterInitialization方法
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
====================打個廣告,歡迎關注====================
QQ: |
412425870 |
微信公眾號:Cay課堂 |
|
csdn部落格: |
http://blog.csdn.net/caychen |
碼雲: |
https://gitee.com/caychen/ |
github: |
https://github.com/caychen |
點選群號或者掃描二維碼即可加入QQ群:328243383(1群) |
|
點選群號或者掃描二維碼即可加入QQ群: |
|
--------------------- 作者:caychen 來源:CSDN 原文:https://blog.csdn.net/caychen/article/details/83008897?utm_source=copy 版權宣告:本文為博主原創文章,轉載請附上博文連結!