spring之Bean的生命周期

时间:2022-12-24 15:54:33


一、Bean的生命周期之五步

Bean的生命周期按照粗略的五步的话:

  • 第一步:实例化Bean(调用无参数构造方法)
  • 第二步:Bean属性赋值(调用set方法)
  • 第三步:初始化Bean(调用Bean的init方法,需要自己写自己配)
  • 第四步:使用Bean
  • 第五步:销毁Bean(调用Bean的destory方法,需要自己写自己配

spring之Bean的生命周期

需要手动关闭spring容器

        //销毁Bean 必须手动关闭Spring容器
        ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) applicationContext;
        context.close();

需要手动指定初始化方法和销毁方法

init-method="initBean" destroy-method="destroyBean"

1、准备User类

无参构造 name属性以及set方法

public class User {
    private String name;

    public void setName(String name) {
        System.out.println("第二步:给对象的属性赋值。");
        this.name = name;
    }

    public User() {
        System.out.println("第一步:无参数构造方法执行。");
    }
    public void initBean(){
        System.out.println("第三步:初始化Bean。");
    }
    public void destroyBean(){
        System.out.println("第五步:销毁Bean。");
    }
}

2、spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="user" class="com.bjpowernode.spring.bean.User"
          init-method="initBean" destroy-method="destroyBean">
        <property name="name" value="小白"></property>

    </bean>
</beans>

3、测试类

    @Test
    public void testBeanLifeCircle(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        User user = applicationContext.getBean("user", User.class);
        System.out.println("第四步:使用Bean:"+user);
        //销毁Bean 必须手动关闭Spring容器
        ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) applicationContext;
        context.close();
    }

4、运行结果

spring之Bean的生命周期

二、Bean的生命周期之七步

在以上的五步中,第三步是初始化Bean,如果还想在初始化前和初始化后添加代码,可以加入”Bean后处理器“ ----”BeanPostProcessor“

Bean生命周期七步:

  • 第一步:实例化Bean(调用无参数构造方法)
  • 第二步:Bean属性赋值(调用set方法)
  • 第三步:执行”Bean后处理器“的before方法
  • 第四步:初始化Bean(调用Bean的init方法,需要自己写自己配)
  • 第五步:执行”Bean后处理器“的after方法
  • 第六步:使用Bean
  • 第七步:销毁Bean(调用Bean的destory方法,需要自己写自己配)
    spring之Bean的生命周期

1、实现BeanPostProcessor类

编写一个类实现BeanPostProcessor类,并且重写before和after方法:

出现return 报错的现象可能是jdk版本太低 改为1.8即可

public class LogBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("第三步:执行”Bean后处理器“的before方法");
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("第五步:执行”Bean后处理器“的after方法");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

2、配置文件

需要在配置文件中进行配置

注意:这个Bean后处理器将作用于整个配置文件中所有的Bean

<bean class="com.bjpowernode.spring.bean.LogBeanPostProcessor"></bean>

完整的:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean class="com.bjpowernode.spring.bean.LogBeanPostProcessor"></bean>

    <bean id="user" class="com.bjpowernode.spring.bean.User"
          init-method="initBean" destroy-method="destroyBean">
        <property name="name" value="小白"></property>

    </bean>
</beans>

3、运行结果:

spring之Bean的生命周期

三、Bean的生命周期之十步

比七步添加的三步在哪里?

  • 在”Bean后处理器“before方法之前(检查Bean是否实现了Aware的相关接口,并设置相关依赖)
  • 在”Bean后处理器“before方法之后(检查Bean是否实现了InitializingBean接口,并调用接口方法)
  • 销毁Bean之前或使用Bean之后(检查Bean是否实现了DisposableBean接口,并调用接口方法)
    添加的这三步的特点:都是在检查这个Bean是否实现了某些特定的接口,如果实现了这些接口,则spring容器会调用这些接口中的方法

1、点位1

实现BeanNameAware, BeanClassLoaderAware, BeanFactoryAware 接口

public class User implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {
    private String name;

    public void setName(String name) {
        System.out.println("第二步:给对象的属性赋值。");
        this.name = name;
    }

    public User() {
        System.out.println("第一步:无参数构造方法执行。");
    }
    public void initBean(){
        System.out.println("第四步:初始化Bean。");
    }
    public void destroyBean(){
        System.out.println("第七步:销毁Bean。");
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("Bean这个类的加载器:"+classLoader);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("生产这个Bean的工厂对象是:"+beanFactory);
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("这个Bean的名字是:"+name);
    }
}

spring之Bean的生命周期

2、点位2

实现InitializingBean接口

public class User implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, InitializingBean {

    public void setName(String name) {
        System.out.println("第二步:给对象的属性赋值。");
    }

    public User() {
        System.out.println("第一步:无参数构造方法执行。");
    }
    public void initBean(){
        System.out.println("第四步:初始化Bean。");
    }
    public void destroyBean(){
        System.out.println("第七步:销毁Bean。");
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("Bean这个类的加载器:"+classLoader);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("生产这个Bean的工厂对象是:"+beanFactory);
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("这个Bean的名字是:"+name);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean's afterPropertiesSet执行。");
    }
}

spring之Bean的生命周期

3、点位3

实现DisposableBean接口

public class User implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, InitializingBean,DisposableBean {

    public void setName(String name) {
        System.out.println("第二步:给对象的属性赋值。");
    }

    public User() {
        System.out.println("第一步:无参数构造方法执行。");
    }
    public void initBean(){
        System.out.println("第四步:初始化Bean。");
    }
    public void destroyBean(){
        System.out.println("第七步:销毁Bean。");
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("Bean这个类的加载器:"+classLoader);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("生产这个Bean的工厂对象是:"+beanFactory);
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("这个Bean的名字是:"+name);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean's afterPropertiesSet执行。");
    }

    @Override

    public void destroy() throws Exception {
        System.out.println("DisposableBean's destroy执行");
    }
}

spring之Bean的生命周期

四、Bean的作用域

  • spring容器只对singleton的Bean进行完整的生命周期管理
  • 如果是prototype作用域,Spring容器只负责将该Bean初始化完毕,等客户端一旦获取到该Bean之后,Spring容器就不再管理该对象的生命周期了(生出来就不管了)
    测试:
    在配置文件中加入
    scope=“prototype”
    spring之Bean的生命周期
    客户端获取之后,就不再继续管之后的生命周期了