spring Bean的生命周期以及初始化销毁过程

Bean的生命周期

1、创建

2、初始化

3、销毁

的过程

自定义

1、初始化和销毁方法

1、指定初始化销毁方法

在被声明的Bean里面自己定义初始化和销毁的方法,然后通过@Bean注解的属性,制定初始化和销毁的方法;

初始化方法调用时机:在bean创建完成,然后赋值做好了以后,就会调用init方法;【具体调用流程,详见springBean创建过程】

销毁:spring容器被关闭的时候;

关于销毁方法的执行:需要注意只有单实例的bean,容器关闭时,才会执行销毁方法;如果bean是prototype时,这个时候就不会执行销毁方法。为什么,因为多实例bean,spring容器只管给你创建新的,但是具体啥时候要被销毁,对于

spring容器来讲。由使用者自行决定;spring只负责生产。

public class BeanLife {

    public BeanLife() {
        System.out.println("BeanLife构造函数执行");
    }

    public void init(){
        System.out.println("指定init方法");
    }

    public void destroy(){
        System.out.println("指定destroy方法");
    }
}

@Configuration
public class Config4 {

    @Bean(initMethod = "init",destroyMethod = "destroy")
    public BeanLife beanLife(){
        return new BeanLife();
    }
}

public static void main(String[] args) throws Exception{
    AnnotationConfigApplicationContext configApplicationContext =
                new AnnotationConfigApplicationContext(Config4.class);
        String[] beanDefinitionNames = configApplicationContext.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }
    System.out.println("***************************");
    //关闭容器
    configApplicationContext.close();

}

//控制台输出(关键内容)
BeanLife构造函数执行
指定init方法
指定destroy方法

2、实现接口InitializingBean  DisposableBean

InitializingBean 初始化接口,里面有方法afterPropertiesSet

DisposableBean 销毁接口,里面有方法destroy

public class BeanLife implements InitializingBean, DisposableBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("实现了InitializingBean接口afterPropertiesSet方法被执行");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("实现了DisposableBean接口destroy方法被执行");
    }

}

输出

//控制台输出
BeanLife构造函数执行
实现了InitializingBean接口afterPropertiesSet方法被执行
指定init方法
实现了DisposableBean接口destroy方法被执行
指定destroyCustom方法

1、对于自定义的初始化方法优先级小于实现了接口InitializingBean的afterPropertiesSet方法
2、自定义的销毁方法优先级小于DisposableBean接口destroy方法

3、使用JSR250规范

定义的注解

以下代码直接加载BeanLife类里面

@PostConstruct
public void initJsr250(){
	System.out.println("initJsr250规范注解初始化");
}

@PreDestroy
public void destroyJsr250(){
	System.out.println("destroyJsr250规范注解初始化");
}

执行流程
BeanLife构造函数执行//构造函数执行
initJsr250规范注解初始化//jsr250规范
实现了InitializingBean接口afterPropertiesSet方法被执行//afterPropertiesSet
指定init方法//自定义的

destroyJsr250规范注解初始化//jsr250规范
实现了DisposableBean接口destroy方法被执行//destroy
指定destroyCustom方法//自定义的

4、beanPostProcessor bean的后置处理器

在bean处理前后,进行的一些处理工作

//注意:使用的时候,一定要让他成为spring容器的组件,否则他就无法工作
BeanPostProcessor接口的方法
//初始化之前
postProcessBeforeInitialization
//初始化之后
postProcessAfterInitialization

在任何初始化调用之前工作;也就是在前面的1-3步骤初始化;

在调用初始化之后,也就是前面1-3步骤之后再调用;

//注意哈,在自己搞的时候,虽然你加了这个组件标识;但是如果是自己搞的启动类时,要记得包扫描,否则就算加了,组件也不会加载到spring容器中哟
//@ComponentScan("com.wolf.bean")
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    /**
     * 在初始化之前
     *
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("MyBeanPostProcessor-postProcessBeforeInitialization:" + beanName);
        return bean;
    }

    /**
     * 在初始化之后
     *
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("MyBeanPostProcessor-postProcessAfterInitialization:" + beanName);
        return bean;
    }
}

在分析springbean的创建过程的时候,通过debug的方法,看看方法调用栈,就能看见方法的执行过程;

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory的方法initializeBean

关键点

1、后置处理器执行,为null时,就不在调用了。直接返回

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	//在spring容器找到所有的bean后置处理器(最开始我们怼进行的,这里就包含了)spring容器启动的时候,晓得加
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		Object current = processor.postProcessBeforeInitialization(result, beanName);
		//这里重点,如果执行的bean后置处理器,如果返回为null时,管你后面还有好多bean后置处理器,通通不执行,return返回
		//applyBeanPostProcessorsAfterInitialization依旧如此
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

2、大概的执行链路

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory的方法doCreateBean
populateBean(beanName, mbd, instanceWrapper);//给bean的属性赋值
xposedObject = initializeBean(beanName, exposedObject, mbd)//初始化bean
  1、Aware 实现对当前实例实现了Aware接口的属性设置
  2、applyBeanPostProcessorsBeforeInitialization 执行bean后置处理器before
  3、invokeInitMethods 调用初始化方法
    --JSR250规范的初始化方法,优先于下面1和2的执行
    1、InitializingBean 执行的afterPropertiesSet
    2、执行自定义的initMethod
  4、applyBeanPostProcessorsAfterInitialization 执行bean后置处理器after

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值