还不了解Bean的生命周期?

Bean的生命周期

要求
  • 有spring基础
  • 了解过一些设计模式
1.什么是生命周期?

生命周期就是指一个对象的生老病死,在bean中简单的说就是bean的创建到初始化再到bean的销毁的过程(创建->初始化->销毁),然而在spring中正是由spring容器帮我们管理着bean的生命周期,同时也给我们提供了5种方法来控制生命周期,下面依次介绍。

2.自定义Bean初始化、销毁方法

在spring中我们可以自己定义bean的初始化方法及销毁方法,为什么要自己去定义初始化方法、销毁方法?有时候需要在初始化时进行一些业务的处理,在销毁的时候关闭一些资源,这时候就需要我们自定义初始化、销毁方法,这里以注解的形式演示:

package org.example.bean;

/**
 * 自定义普通类Computer
 * @author JHS
 */
public class Computer {

    private String name; //电脑名

    Computer(){
        System.out.println("创建--(电脑开机)");
    }

    public void init(){
        System.out.println("初始化--(准备环境)");
    }

    public void destroy(){
        System.out.println("销毁--(电脑关机)");
    }
}

这里定义了一个自定义的电脑类,包含无参构造、自定义初始化方法、销毁方法,接下来我们将要写一个配置类以注解的形式将Computer类加入到spring容器中。

package org.example.bean;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 说明:@Configuration相当于我们以前写的xml配置文件,@Bean相当于容器中的bean
 * @author JHS
 */

@Configuration
public class ComputerConfig {

    //initMethod自定义初始化方法、destroyMethod自定义销毁方法
    @Bean(initMethod = "init",destroyMethod = "destroy")
    public Computer computer(){

       return new Computer();
    }
}

启动类:

package org.example.bean;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * 启动类
 * @author JHS
 */
public class Main {
    public static void main(String[] args) {
        //以注解形式创建应用ComputerConfig.class配置类替换以前的xml
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ComputerConfig.class);
        //从容器中获取实例computer既是配置类方法名(bean名字)
         context.getBean("computer");

        //关闭此应用程序上下文,销毁其bean工厂中的所有bean
        context.close();
    }

}

结果显示:

在这里插入图片描述

我们可以看到控制台打印了我们自动定义的初始化方法与销毁方法,此只是在单例模式下的显示,多例模式下不会调用销毁方法。

3.spring提供的初始化、销毁接口

spring为我们提供了InitializingBean,DisposableBean两个接口,分别代表初始化与销毁,我们只需要实现这两个接口,然后重写它的方法就能达到bean的初始化和销毁,控制台显示效果与上面一样。

package org.example.bean;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

/**
 * @author JHS
 */
public class LifeCycle implements InitializingBean, DisposableBean {
	//与@PreDestroy注解类似,在容器销毁bean之前通知我们进行清理工作
    public void destroy() throws Exception {
        System.out.println("销毁");
    }
	//与@PostConstruct注解类似,在bean创建完成并且属性赋值完成;来执行初始化方法
    public void afterPropertiesSet() throws Exception {
        System.out.println("初始化");
    }
}
4.Bean的后置处理器

spring为我们提供了BeanPostProcessor后置处理器,主要是方便我们在初始化之前和初始化之后进行一些操作,BeanPostProcessor接口提供了两个抽象方法,一个是postProcessBeforeInitialization方法,在初始化之前进行调用,一个是postProcessAfterInitialization方法,在初始化之后进行调用。

package org.example.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 * 后置处理器类并通过@Component加入到容器中
 * @author JHS
 */
@Component
public class BeanProcessor  implements BeanPostProcessor {

     /**
    * 初始化之前
    * @param: [bean 容器中的Bean, beanName bean名字]
    * @return: java.lang.Object
    */
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(bean+"--->"+beanName);
        return bean;
    }
    
	/**
    * 初始化之后
    * @param: [bean, beanName]
    * @return: java.lang.Object
    */
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(bean+"--->"+beanName);
        return bean;
    }
}
package org.example.bean;

/**
 * 自定义普通类Computer
 * @author JHS
 */
public class Computer {

    private String name; //电脑名

    Computer(){
        System.out.println("创建--(电脑开机)");
    }

    public void init(){
        System.out.println("初始化--(准备环境)");
    }

    public void destroy(){
        System.out.println("销毁--(电脑关机)");
    }
}

配置类:

package org.example.bean;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * 配置类,相当于spring中的xml配置文件
 * @author JHS
 */
@ComponentScan("org.example.bean")
@Configuration
public class ComputerConfig {
	//initMethod与destroyMethod是上面我们自定义的初始化及销毁方法
    @Bean(initMethod = "init",destroyMethod = "destroy")
    public Computer computer(){

       return new Computer();
    }
}

启动类与上面自定义的一样,然后启动:

在这里插入图片描述

5.后置处理器原理

为了更加清楚的了解到后置处理器原理,这里我们在BeanPostProcessor接口里面的两个方法分别打上断点,以方便我们调试,然后开启Debug模式。

在这里插入图片描述

根据方法栈中的方法依次跟踪到AbstractAutowireCapableBeanFactory抽象类中的doCreateBean()方法。

在这里插入图片描述

接下来我们来看doCreateBean()方法里面的内容

在这里插入图片描述

接下来我们点击initializaeBean(beanName,exposed,mbd)进入方法内部,在这个方法内部可以看到applyBeanPostProcessorsBeforeInitialization ()与applyBeanPos tProcessorsAfterInitialization()方法,这就是Bean初始化之前与之后调用的方法,而invokeInitMethods()方法则是调用自己实现的初始化方法等。

在这里插入图片描述

再点击applyBeanPostProcessorsBeforeInitialization ()方法进入,这里对每个Bean处理器列表进行了遍历,遍历得到容器中所有的BeanPostProcessor,挨个执行beforeInitialization,一但返回null就跳出for循环,不会执行后面的processor.postProcessBeforeInitialization。

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值