Spring framework(四)SpringBean生命周期

一、执行流程

传统Java应用中,Bean的生命周期很简单,使用关键字new实例化Bean,不需要时,由Java GC回收。

Spring中Bean的生命周期较为复杂:Bean的定义-> Bean的初始化 -> Bean的使用 -> Bean的销毁。

Spring根据Bean的作用域来选择管理方式,对于singleton的Bean,Spring能够精准地知道该Bean何时被创建、何时初始化完成、何时被销毁;对于prototype作用域的Bean,Spring只负责创建,当容器创建Bean实例后,实例交由客户端代码管理,Spring容器不再跟踪其生命周期。

1.1、生命周期流程图

在这里插入图片描述

Bean的生命周期整个执行过程:

  1. Spring启动,查找并加载需要被Spring管理的Bean,并实例化Bean。
  2. 利用依赖注入完成Bean中所有属性值的配置注入。
  3. 如果Bean实现了BeanNameAware接口,则Spring调用Bean的setBeanName()方法传入当前Bean的id值。
  4. 如果Bean实现了BeanFactoryAware接口,则Spring调用setBeanFactory()方法传入当前工厂实例的引用。
  5. 如果Bean实现了ApplicationContextAware接口,则Spring调用setApplicationContext()方法传入当前ApplicationContext实例的引用。
  6. 如果Bean实现了BeanPostProcesor接口,则Spring调用该接口的预初始化方法postProcessBeforeInitialzation()对Bean进行加工操作,Spring AOP就是利用它实现的。
  7. 如果Bean实现了InitializingBean接口,则Spring将调用afterPropertiesSet()方法。
  8. 如果配置文件中通过init-method属性指定了初始化方法,则调用该初始化方法。
  9. 如果BeanPostProcessor和Bean关联,则Spring将调用该接口的初始化方法postProcessAfterInitialization()。此时,Bean已经在应用系统中使用了。
  10. 如果在中指定了该Bean的作用域为singleton,则将该Bean放入SpringIoC的缓存池中,触发Spring对该Bean的生命周期管理;如果作用域为prototype,则将该Bean交给调用者管理,Spring不管理该Bean。
  11. 如果Bean实现了DisposableBean接口,则Spring会调用destory()方法销毁Bean;如果在配置文件中指定了destory-method,Spring将调用该方法对Bean进行销毁。

Spring官方提供了3中法法实现初始化回调和销毁回调:

  1. 实现InitializingBean和DisposableBean接口
  2. 在XML中配置init-method和destory-method
  3. 使用@PostConstruct和@PreDestory注解

Bean中有杜仲生命周期回调方法时,优先级:注解 > 接口 > XML

二、初始化回调

2.1、使用接口

org.springframework.beans.factory.InitializingBean接口中存在方法:

void afterPropertiesSet() throws Exception;

可以在自己的类实现InitializingBean接口,重写afterPropertiesSet()方法,指定Bean初始化后需要执行的操作。

<bean id="test" class="com.jsonliu.bean.Test"></bean>
public class Test implements InitializingBean {
 
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Test初始化后执行的操作");
    }
}

2.2、配置XML

可以通过init-method属性指定Bean初始化后执行的方法

    <bean id="test" class="com.jsonliu.bean.Test" init-method="init"></bean>
public class Test implements InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("实现InitializingBean接口的初始化方法");
    }

    public void init(){
        System.out.println("XML中指定init-method的初始化方法");
    }
}

2.3、使用注解

使用@PostConstruct注解标明该方法为Bean初始化后的方法

public class Test implements InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("实现InitializingBean接口的初始化方法");
    }

    public void init(){
        System.out.println("XML中指定init-method的初始化方法");
    }

    @PostConstruct
    public void initMethod(){
        System.out.println("@PostConstruct注解指定的初始化方法");
    }
}

三、销毁回调

3.1、使用接口

实现接口org.springframework.beans.factory.DisposableBean中方法:

void destroy() throws Exception; 

该方法指定了Bean销毁后执行的方法

public class Test implements   DisposableBean { 
 
    @Override
    public void destroy() throws Exception {
        System.out.println("实现了DisposableBean的销毁方法");
    }
}

3.2、配置XML

可以通过destroy-method属性指定Bean销毁后执行的方法

    <bean id="test" class="com.jsonliu.bean.Test"  destroy-method="destroyMethod"></bean>
public class Test implements  DisposableBean {
 
    @Override
    public void destroy() throws Exception {
        System.out.println("实现了DisposableBean的销毁方法");
    }

    public void destroyMethod(){
        System.out.println("XML中指定了destroy-method的销毁方法");
    } 
}

3.3、使用注解

使用@PreDestroy注解标明该方法为Bean销毁前执行的方法


public class Test implements   DisposableBean {
 
    @Override
    public void destroy() throws Exception {
        System.out.println("实现了DisposableBean的销毁方法");
    }

    public void destroyMethod(){
        System.out.println("XML中指定了destroy-method的销毁方法");
    }

    @PreDestroy
    public void destroyMethod2(){
        System.out.println("@PreDestroy注解指定的销毁方法");
    }
}

补充:使用 AbstractApplicationContext 类的 registerShutdownHook() 方法,来确保正常关机并调用相关的 destroy() 方法

public class MainApp {
    public static void main(String[] args) {
        AbstractApplicationContext context=new ClassPathXmlApplicationContext("Beans.xml");
 
        context.registerShutdownHook();
    }
}

四、默认的初始化和销毁方法

多个Bean需要使用相同的初始化和夕会方法,可以在xml的Beans节点使用default-init-method和default-destroy-method属性:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context
   https://www.springframework.org/schema/context/spring-context.xsd" default-destroy-method="destroyMethod" default-init-method="init">

    <bean id="helloWorld" class="com.jsonliu.bean.HelloWorld" scope="prototype">
    </bean>

    <bean id="test" class="com.jsonliu.bean.Test" ></bean> 

</beans>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑谈子云亭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值