Spring 中Bean的生命周期及后置处理器使用

内容来自【自学星球】

欢迎大家来了解我的星球,和星主(也就是我)一起学习 Java ,深入 Java 体系中的所有技术。我给自己定的时间是一年,无论结果如何,必定能给星球中的各位带来点东西。

想要了解更多,欢迎访问👉:自学星球

--------------SSM系列源码文章及视频导航--------------

创作不易,望三连支持!

SSM源码解析视频

👉点我

Spring

  1. Spring 中注入 Bean 的各种骚操作做
  2. Spring 中Bean的生命周期及后置处理器使用
  3. Spring 中容器启动分析之refresh方法执行之前
  4. Spring refresh 方法分析之一
  5. Spring refresh 方法之二 invokeBeanFactoryPostProcessors 方法解析
  6. Spring refresh 方法分析之三
  7. Spring refresh 方法之四 finishBeanFactoryInitialization 分析
  8. Spring AOP源码分析一
  9. Spring AOP源码分析二
  10. Spring 事务源码分析

SpringMVC

  1. SpringMVC 启动流程源码分析
  2. SpringMVC 请求流程源码分析

MyBatis

  1. MyBatis 源码分析之 SqlSessionFactory 创建
  2. MyBatis 源码分析之 SqlSession 创建
  3. MyBatis 源码分析之 Mapper 接口代理对象生成及方法执行
  4. MyBatis 源码分析之 Select 语句执行(上)
  5. MyBatis 源码分析之 Select 语句执行(下)
  6. MyBatis 源码分析一二级缓存

---------------------【End】--------------------

一、生命周期

1.1 Bean 指定 init 方法和 destroy 方法

1)编写 People 类

public class People {

    private String name;

    public People() {
        System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
    }

    public void init() {
        System.out.println(this.getClass().getName() + " 中的 init 被调用...");
    }

    public void destroy() {
        System.out.println(this.getClass().getName() + " 中的 destroy 被调用...");
    }
}

2)在配置类中指定初始化方法和销毁方法

@Configuration
public class StudySpringConfiguration {
    
    @Bean(initMethod = "init", destroyMethod = "destroy")
    public People people() {
        People people = new People();
        people.setName("J3");
        return people;
    }
}

3)测试

public class StudySpringMain {

    public static void main(String[] args) {
        // 读取配置文件启动
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-service.xml");

        People bean = applicationContext.getBean(People.class);
        System.out.println(bean);
        applicationContext.close();
    }
}

2.1 JSR250规范提供的,@PostConstruct 和 @PreDestroy标注的方法

1)编写 People 类

public class People {

    private String name;

    public People() {
        System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
    }
    @PostConstruct
    public void init() {
        System.out.println(this.getClass().getName() + " 中的 init 被调用...");
    }
    @PreDestroy
    public void destroy() {
        System.out.println(this.getClass().getName() + " 中的 destroy 被调用...");
    }
}

2)在配置类中指定初始化方法和销毁方法

@Configuration
public class StudySpringConfiguration {
    
    @Bean
    public People people() {
        People people = new People();
        people.setName("J3");
        return people;
    }
}

3)测试

public class StudySpringMain {

    public static void main(String[] args) {
        // 读取配置文件启动
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-service.xml");

        People bean = applicationContext.getBean(People.class);
        System.out.println(bean);
        applicationContext.close();
    }
}

二、Bean 的各种后置处理器

2.1 BeanPostProcessor 后置处理器

注意该类需要被扫描到

1)编写 PeopleBeanPostProcessor 实现 BeanPostProcessor 接口

@Component
public class PeopleBeanPostProcessor implements BeanPostProcessor {

    public PeopleBeanPostProcessor() {
        System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        System.out.println(this.getClass().getName() + " 中的 postProcessBeforeInitialization 被调用...");

        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        System.out.println(this.getClass().getName() + " 中的 postProcessAfterInitialization 被调用...");

        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

2)测试

public class StudySpringMain {
    public static void main(String[] args) {
        // 读取配置文件启动
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-service.xml");
    }
}

BeanPostProcessor 是拦截所有 Bean 的创建过程,在初始化方法前后做相关处理

2.2 InitializingBean 及 DisposableBean 后置处理器

1)编写 MyInitializingBean 并实现相关接口

@Component
public class MyInitializingBean implements InitializingBean, DisposableBean {

    public MyInitializingBean() {
        System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
    }


    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println(this.getClass().getName() + " 中的 afterPropertiesSet 被调用...");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println(this.getClass().getName() + " 中的 destroy 被调用...");
    }
}

2)测试

public class StudySpringMain {
    public static void main(String[] args) {
        // 读取配置文件启动
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-service.xml");
    }
}

InitializingBean 和 DisposableBean 都是作用于当前 Bean ,InitializingBean 在其构造方法执行完成后调用,DisposableBean 在其 Bean 卸载的时候调用。

三、Bean 工厂后置处理器

1)编写实体

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
    // Bean定义加载完成调用,调用一次(所有Bean加载完成之后,才会执行)
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println(this.getClass().getName() + " 中的 postProcessBeanFactory 被调用...");
    }
}

执行时机:所有 Bean 定义被加载到 BeanDefinition 中时才进行执行。

那么这就给我们留下了很多做小动作的事情,因为此时 Bean 只是加载了配置,还未进行任何实例化。如,我们可以对加载的 Bean 是否单例进行修改等。

四、BeanDefinitionRegistryPostProcessor 后置处理器

1)编写实体

public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
        // Bean定义还未开始加载之前调用,调用一次
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        System.out.println(this.getClass().getName() + " 中的 postProcessBeanDefinitionRegistry 被调用...");
    }

        // Bean定义加载完成调用,调用一次
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println(this.getClass().getName() + " 中的 postProcessBeanFactory 被调用...");
    }
}

BeanDefinitionRegistryPostProcessor 继承 BeanFactoryPostProcessor 接口。

它的执行时机是在 Bean 的定义还未加载之前调用,这时,我们可以自己忘容器中添加相关的 Bean 定义。

好了,今天的内容到这里就结束了,我是 【J3】关注我,我们下期见


  • 由于博主才疏学浅,难免会有纰漏,假如你发现了错误或偏见的地方,还望留言给我指出来,我会对其加以修正。

  • 如果你觉得文章还不错,你的转发、分享、点赞、留言就是对我最大的鼓励。

  • 感谢您的阅读,十分欢迎并感谢您的关注。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

J3code

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

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

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

打赏作者

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

抵扣说明:

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

余额充值