您的位置 首页 > 数码极客

Spring生命周期简述

Spring的生命周期主要指创建、初始化、销毁。Bean的生命周期主要由容器进行管理,我们可以自定义bean的初始化和销毁方法,容器在bean进行到生命周期的特定时间点,来调用自定义的初始化和销毁方法。

示例代码地址:

一 初始化和销毁方式

1.1 指定初始化前方法和容器销毁后方法

init-method destory-method

单实例bean下自定义bean的初始化和销毁方法,在容器关闭时会调用当前bean的initMethod和destoryMethod方法

多实例bean 只有在调用getBean(name)时才会初始化bean,并且容器不会管理多实例bean,所以容器关闭时,不会调用bean的自定义初始化和销毁bean

package com.;

import lombok.ex;

import org.;

/**

* \* Created with IntelliJ IDEA.

* \* @author: wucj

* \* @date: 2020/9/16 12:58

* \* @description:

* \

*/

@Slf4j

public class CycleOne {

public CycleOne() {

log.info("{}...constructor...",().getSimpleName());

}

public void init(){

log.info("{}...init...",().getSimpleName());

}

public void destory(){

log.info("{}...destory...",().getSimpleName());

}

}

1.2 让Bean实现InitializingBean, DisposableBean 接口

package com.;

import lombok.ex;

import org.;

import org.;

/**

* \* Created with IntelliJ IDEA.

* \* @author: wucj

* \* @date: 2020/9/16 12:58

* \* @description:

* \

*/

@Slf4j

public class CycleTwo implements InitializingBean, DisposableBean {

public CycleTwo() {

log.info("{}...constructor...", ().getSimpleName());

}

// 容器移除对象之后调用

@Override

public void destroy() throws Exception {

log.info("{}...destroy...", ().getSimpleName());

}

// 对象创建并赋值完成之后调用

@Override

public void afterPropertiesSet() throws Exception {

log.info("{}...afterPropertiesSet...", ().getSimpleName());

}

}

1.3 使用jsr250规则(java规范)定义的两个注解来实现

package com.;

import lombok.ex;

import javax.anno;

import javax.anno;

/**

* \* Created with IntelliJ IDEA.

* \* @author: wucj

* \* @date: 2020/9/16 12:58

* \* @description:

* \

*/

@Slf4j

public class CycleThree{

public CycleThree() {

log.info("{}...constructor...", ().getSimpleName());

}

// 容器移除对象之后调用

@PreDestroy

public void methord1(){

log.info("{}...destroy...", ().getSimpleName());

}

// 对象创建并赋值完成之后调用

@PostConstruct

public void methord2() {

log.info("{}...afterPropertiesSet...", ().getSimpleName());

}

}

bean注入到容器中:

package com.;

import com..CycleOne;

import com..CycleThree;

import com..CycleTwo;

import org.;

import org.;

import org.;

/**

* \* Created with IntelliJ IDEA.

* \* @author: wucj

* \* @date: 2020/9/16 12:57

* \* @description:

* \

*/

@Configuration

// 扫描指定包路径下的所有bean

@ComponentScan("com.")

public class CycleConfig {

/**

* 自定义bean的初始化和销毁方法,在容器关闭时会调用当前bean的initMethod和destoryMethod方法

* 注意1:单实例下可以调用实例的initMethod和destoryMethod方法,多实例无法调用。

* 注意2:

* @return

*/

@Bean(initMethod = "init",destroyMethod = "destory")

// 多实例不能调用initMethod和destoryMetod方法

// @Scope("prototype")

public CycleOne cycleOne(){

return new CycleOne();

}

@Bean

public CycleTwo cycleTwo(){

return new CycleTwo();

}

@Bean

public CycleThree cycleThree(){

return new CycleThree();

}

}

容器启动和销毁:

package com.;

import com..CycleConfig;

import org.;

/**

* \* Created with IntelliJ IDEA.

* \* @author: wucj

* \* @date: 2020/9/16 13:01

* \* @description: bean生命周期源码跟踪与学习

* \

*/

public class CycleConfigTest {

public static void main(String[] args) {

// 启动容器

AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContex);

/**

* 注意1:单实例下自定义bean的初始化和销毁方法,在容器关闭时会调用当前bean的initMethod和destoryMethod方法

* 注意2:多实例bean 只有在调用getBean(name)时才会初始化bean,并且容器不会管理多实例bean,所以容器关闭时,不会调用bean的自定义初始化和销毁bean

* @return

*/

// 关闭容器

a();

}

}

只有以上三种可以实现bean的自定义初始化和销毁调用;

二 后置处理器

后置处理器负责在初始化方法前后调用;

接口BeanPostProcessor是bean的后置处理器,在bean初始化前、后进行方法拦截;

方法1:

default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

return bean;

}

调用时机:在任何初始化方法调用之前进行后置处理工作(initMethod之前、initializingBean的afterPropertiesSet初始化之前)

方法2:

default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

return bean;

}

调用时机:在任何初始化方法调用之后进行后置处理工作(initMethod之后、initializingBean的afterPropertiesSet初始化之后)

总结:单实例bean的整个生命周期都可以进行控制;

三 容器启动及BeanPostProcessor源码分析

针对CycleConfigTest进行debug:以下所有断点位置都是源码的位置,请使用示例源码项目断点:下载

断点1:org/springframework/context/annotation

refresh();

断点2:org/springframework/context/suppor

// Instantiate all remaining (non-lazy-init) singletons. 实例化非懒加载单例bean

finishBeanFactoryInitialization(beanFactory);

断点3:org/springframework/context/suppor

// Instantiate all remaining (non-lazy-init) singletons.

beanFac();

断点4:org/springframework/beans/factory/suppor

getBean(beanName);

断点5:org/springframework/beans/factory/suppor

return doGetBean(name, null, null, false);

断点6:org/springframework/beans/factory/suppor

断点7:org/springframework/beans/factory/suppor

断点8:org/springframework/beans/factory/suppor

return createBean(beanName, mbd, args);

断点9:org/springframework/beans/factory/suppor

断点10:org/springframework/beans/factory/suppor

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

断点11:org/springframework/beans/factory/suppor

断点12:org/springframework/beans/factory/suppor

populateBean(beanName, mbd, instanceWrapper); // 属性赋值

exposedObject = initializeBean(beanName, exposedObject, mbd); // 初始化

断点13:org/springframework/beans/factory/suppor

// 初始化方法调用之前

wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

断点14:org/springframework/beans/factory/suppor

// 初始化

invokeInitMethods(beanName, wrappedBean, mbd);

断点15:org/springframework/beans/factory/suppor

// 初始化方法调用后

wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

责任编辑: 鲁达

1.内容基于多重复合算法人工智能语言模型创作,旨在以深度学习研究为目的传播信息知识,内容观点与本网站无关,反馈举报请
2.仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证;
3.本站属于非营利性站点无毒无广告,请读者放心使用!

“java864”边界阅读