spring提供的关于bean生命周期的接口

简介: 先看一张图:spring4.x 企业实战spring版本:4.3.171、bean自身的生命周期接口1.1、实现 InitializingBean、DisposableBean 接口这2个接口,会要求你实现2个方法...

先看一张图:spring4.x 企业实战

clipboard.png

spring版本:4.3.17
1、bean自身的生命周期接口

1.1、实现 InitializingBean、DisposableBean 接口
这2个接口,会要求你实现2个方法

@Component
public class BeanSelf implements InitializingBean, DisposableBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet");
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("destroy");
    }
}

afterPropertieseSet 会在属性设置完毕,调用,这里的属性设置,指的是Bean的依赖注入。比如。在 BeanSelf中注入 BeanSelf2

private BeanSelf2 beanSelf2
@Autowired
public void setBeanSelf2(BeanSelf2 beanSelf2) {
    System.out.println("注入BeanSelf2");
    this.beanSelf2 = beanSelf2
}

运行结果

注入 beanSelf2
afterPropertiesSet
destroy

1.2、使用 @PostConstruct、 @PreDestroy 注解
正如其名:在构造器之后, 即在销毁之前。

public class BeanSelf implements InitializingBean, DisposableBean{

    private BeanSelf2 beanSelf2;
    private BeanSelf3 beanSelf3;

    public BeanSelf(BeanSelf2 beanSelf2) {
        System.out.println("构造器注入 beanSelf2");
        this.beanSelf2 = beanSelf2;
    }

    @Autowired
    public void setBeanSelf3(BeanSelf3 beanSelf3) {
        System.out.println("属性注入 beanSelf3");
        this.beanSelf3 = beanSelf3;
    }

    @PostConstruct
    public void init() {
        System.out.println("PostConstruct");
    }

    @PreDestroy
    public void initDestroy2() {
        System.out.println("PreDestroy");
    }
    
     @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet");
    }
    
    @Override
    public void destroy() throws Exception {
        System.out.println("destroy");
    }
}

运行效果

构造器注入 beanSelf2
属性注入 beanSelf3
PostConstruct   --- 很明显 @PostConstruct 是在构造器之后注入 beanSelf2
afterPropertiesSet ---  PostConstruct 之后
PreDestroy   --- 很明显,是在销毁之前调用的
destroy

小总结:不管是@PostConstruct 或者 实现InitializingBean接口。 都是在Bean实例化完成之后才调用的。

2、beanFactory工厂接口,只调用一次

@Component
public class MyBeanFactory implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        Iterator<String> iterator = configurableListableBeanFactory.getBeanNamesIterator();
        BeanSelf2 beanSelf = (BeanSelf2) configurableListableBeanFactory.getBean("beanSelf2");
        beanSelf.add();
        System.out.println("beanFactoryPostProcessor");
    }
}

@Component
public class BeanSelf2 implements InitializingBean{

    public void add() {
        System.out.println("add");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("beanSelf2 afterPropertiesSet");
    }
}

这个接口的方法会在实例化之前调用。 在postProcessBeanFactory 中,对BeanSelf2提前进行初始化,并调用add方法。

beanSelf2 afterPropertiesSet  -- 调用beanSelf2的afterPropertiesSet方法 
add 
beanFactoryPostProcessor
构造器注入 beanSelf2
属性注入 beanSelf3
PostConstruct
afterPropertiesSet
PreDestroy

BeanFactoryPostProcessor 顾名思义,在这个方法里面可以拿到所有装载的Bean,并在初始化之前对某些Bean进行修改。(此时Bean还未初始化)

3、BeanPostProcessor接口在每个Bean实例之前,都会调用。如果Bean已实例化则不会diaoy

@Component
public class MyBeanPostProcessor implements BeanPostProcessor{
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName +"  =  postProcessBeforeInitialization" );
        if("beanSelf2".equals(beanName)) {
            return null;
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName +"  =  postProcessAfterInitialization");
        return bean;
    }
}

上面这段代码的意思是,在初始化之前,将BeanSelf2 和 BeanSel3 置为null。但是,BeanSelf2不会走到这段代码内,因为在接口BeanFactoryPostProcessor 中,将BeanSelf2提前初始化了。所以输出结果如下

beanSelf2 afterPropertiesSet  --- BeanFactoryPostProcessor中提前初始化
add                        ---  调用BeanSelf2的add方法
beanFactoryPostProcessor   --- 在postProcessBeanFactory 中打印
beanConfig  =  postProcessBeforeInitialization  --调用 BeanPostProcessor
beanConfig  =  postProcessAfterInitialization   --调用 BeanPostProcessor
BeanSelf  构造器注入 beanSelf2                   --BeanSelf 构造器注入属性
beanSelf3  =  postProcessBeforeInitialization  -- 在实例化之前调用 
BeanSelf  属性注入 beanSelf3                    -- 注入之前,BeanSelf3还没实例化,所以在之前调用 BeanPostProcessor
beanSelf  =  postProcessBeforeInitialization   --- beanSelf 在属性设置完毕后,即初始化完毕 调用 BeanPostProcessor#postProcessBeforeInitialization()
BeanSelf  PostConstruct  --  调用被 @PostConstruct 注解声明的方法
afterPropertiesSet     -- 调用 InitializingBean 接口实现的方法
beanSelf  =  postProcessAfterInitialization
beanSelf2 com.xhn3.BeanSelf2@33cb5951
beanSelf3 null      -- 在BeanPostProcessor中返回null。所以这边是null
BeanSelf  PreDestroy
destroy

小总结:BeanPostProcessor#postProcessBeforeInitialization在init-method之前调用,在属性设置完毕后调用。BeanPostProcessor#postProcessAfterInitialization 在InitializingBean#afterPropertiesSet后调用。

4、BeanDefinitionRegistryPostProcessor 注册Bean的接口,在BeanFactoryPostProcesso前调用

@Component
public class MyBeanRegister implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
   
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    }
}

在该方法里面可以直接注册bean。可以提前实例化Bean

运行流程:

clipboard.png

目录
相关文章
|
18天前
|
Java API 微服务
【Spring Boot系列】通过OpenAPI规范构建微服务服务接口
【4月更文挑战第5天】通过OpenAPI接口构建Spring Boot服务RestAPI接口
|
28天前
|
Java 应用服务中间件 Spring
Spring系列文章:Bean的作⽤域
Spring系列文章:Bean的作⽤域
|
28天前
|
Java Spring 容器
Spring系列文章:Bean的获取⽅式
Spring系列文章:Bean的获取⽅式
|
1天前
|
Java Spring
spring boot访问接口报500
spring boot访问接口报500
8 2
|
7天前
|
消息中间件 安全 Java
在Spring Bean中,如何通过Java配置类定义Bean?
【4月更文挑战第30天】在Spring Bean中,如何通过Java配置类定义Bean?
16 1
|
10天前
|
前端开发 Java 数据格式
【Spring系列笔记】定义Bean的方式
在Spring Boot应用程序中,定义Bean是非常常见的操作,它是构建应用程序的基础。Spring Boot提供了多种方式来定义Bean,每种方式都有其适用的场景和优势。
29 2
|
12天前
|
XML 人工智能 Java
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
|
12天前
|
Java 数据库连接 数据库
spring+mybatis_编写一个简单的增删改查接口
spring+mybatis_编写一个简单的增删改查接口
14 2
|
20天前
|
Java 数据库连接 开发者
浅谈Spring的Bean生命周期
浅谈Spring的Bean生命周期
21 1
|
25天前
|
XML Java 数据格式
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
22 0
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道