Bean生命周期

Bean生命周期

Bean生命周期可分为两个阶段:

  • 初始化阶段:从初始化到准备完成可供使用;
  • 销毁阶段:IoC容器shut down时销毁bean。

在这里插入图片描述

Aware接口

Aware接口在Spring框架自身应用比较多,开发者一般很少使用,下面三个比较熟知:

  • BeanFactoryAware:提供setBeanFactory(), 为bean提供BeanFactory实例引用的回调方法;
  • BeanNameAware:提供setBeanName() ,为bean提供name的回调方法;
  • ApplicationContextAware:提供setApplicationContext(),为bean提供ApplicationContext实例引用的回调方法。

例如:

@Component
@ConfigurationProperties(prefix = "singer")
public class Singer implements ApplicationContextAware, BeanNameAware, BeanFactoryAware {
    private String name;
    private String beanName;
    private BeanFactory beanFactory;
    private ApplicationContext applicationContext;

    //setter注入
    public void setName(String name) {
        this.name = name;
    }
    
    public void sing() {
        System.out.println("singing,singing,singing...");
    }

    @Override
    public void setBeanName(String s) {
        this.beanName = s;
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

BeanPostProcessor

BeanPostProcessor有两个方法,运行时,Spring会注入新的bean实例和bean name。

  • postProcessBeforeInitialization:初始化之前的回调接口,在Aware的方法之后,初始化方法之前回调。
  • postProcessAfterInitialization:任何初始化方法(如InitializingBean接口的afterPropertiesSet)之后回调。

这两个方法为容器提供配置bean的时机,不要随便使用。例如,实现这两个方法:

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor postProcessBeforeInitialization method is called : Bean Name " + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor postProcessAfterInitialization method is called : Bean Name " + beanName);
        return bean;
    }

控制台输出非常多,每个bean都会打印一遍。

InitializingBean 和 DisposableBean

InitializingBean接口提供 afterPropertiesSet() 方法,用于自定义初始化逻辑,容器在bean属性设置完后调用。

DisposableBean接口提供 destroy() 方法,用于自定义bean的清理逻辑,在容器关闭后回调。

例如:

public class Singer implements InitializingBean, DisposableBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean afterPropertiesSet method is called");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean destroy method is called");
    }
}

为了看到destroy()方法,修改一下main:

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
        context.registerShutdownHook();
        context.close();
    }

}

总结

package com.example.demo;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "singer")
public class Singer implements ApplicationContextAware, BeanNameAware, BeanFactoryAware, BeanPostProcessor, InitializingBean, DisposableBean {
    private String name;
    private String beanName;
    private BeanFactory beanFactory;
    private ApplicationContext applicationContext;

    public Singer() {
        System.out.println("Singer Constructor called");
    }

    //setter注入
    public void setName(String name) {
        this.name = name;
        System.out.println("Singer setName called");
    }

    public void sing() {
        System.out.println("singing,singing,singing...");
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("BeanNameAware setBeanName method is called : Bean Name " + s);
        this.beanName = s;
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryAware setBeanFactory method is called : BeanFactory " + beanFactory);
        this.beanFactory = beanFactory;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("ApplicationContextAware setApplicationContext method is called : ApplicationContext " + applicationContext);
        this.applicationContext = applicationContext;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor postProcessBeforeInitialization method is called : Bean Name " + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor postProcessAfterInitialization method is called : Bean Name " + beanName);
        return bean;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean afterPropertiesSet method is called");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean destroy method is called");
    }
}

打印顺序是:

Singer Constructor called
BeanNameAware setBeanName method is called : Bean Name singer
BeanFactoryAware setBeanFactory method is called : BeanFactory org.springframework.beans.factory.support.DefaultListableBeanFactory@2203bc9e:
ApplicationContextAware setApplicationContext method is called : ApplicationContext org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@37ee642c
Singer setName called
BeanPostProcessor postProcessBeforeInitialization method is called : Bean Name
InitializingBean afterPropertiesSet method is called
BeanPostProcessor postProcessAfterInitialization method is called : Bean Name
DisposableBean destroy method is called
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值