SpringBoot中Bean生命周期自定义初始化和销毁方法详解

 更新时间:2024年01月24日 09:11:49   作者:浩泽学编程  
这篇文章给大家详细介绍了SpringBoot中Bean生命周期自定义初始化和销毁方法,文中通过代码示例讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下

一、@Bean注解指定初始化和销毁方法

创建BeanTest类,自定义初始化方法和销毁方法。在@Bean注解的参数中指定BeanTest自定义的初始化和销毁方法:销毁方法只有在IOC容器关闭的时候才调用。

代码如下:

/**
 * @Version: 1.0.0
 * @Author: Dragon_王
 * @ClassName: dog
 * @Description: TODO描述
 * @Date: 2024/1/21 22:55
 */
public class BeanTest {
    public BeanTest(){
        System.out.println("BeanTest被创建");
    }

    public void init(){
        System.out.println("BeanTest被初始化");
    }

    public void destory(){
        System.out.println("BeanTest被销毁");
    }
}
/**
 * @Version: 1.0.0
 * @Author: Dragon_王
 * @ClassName: MyConfig
 * @Description: TODO描述
 * @Date: 2024/1/21 22:59
 */
@Configuration
@ComponentScan(("com.dragon.restart1"))
public class MyConfig {
    @Bean(initMethod = "init",destroyMethod = "destory")
    public BeanTest beanTest(){
        return new BeanTest();
    }
}
//测试代码
AnnotationConfigApplicationContext ct = new AnnotationConfigApplicationContext(MyConfig.class);
System.out.println("IoC容器创建完成");

在这里插入图片描述

  • 可以看到调用的是自定义的方法,这里解释一下,测试时,运行完代码块程序就结束了,所哟IoC容器就被关闭,所以调用了IoC销毁方法。同时可以看到初始化方法在对象创建完成后调用。
  • 当组件的作用域为单例时在容器启动时即创建对象,而当作用域为原型(PROTOTYPE)时在每次获取对象的时候才创建对象。并且当作用域为原型(PROTOTYPE)时,IOC容器只负责创建Bean但不会管理Bean,所以IOC容器不会调用销毁方法。

二、实现InitializingBean接口和DisposableBean接口

看一下两接口的方法:

public interface InitializingBean {

	/**
	 * Invoked by the containing {@code BeanFactory} after it has set all bean properties
	 * and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.
	 * <p>This method allows the bean instance to perform validation of its overall
	 * configuration and final initialization when all bean properties have been set.
	 * @throws Exception in the event of misconfiguration (such as failure to set an
	 * essential property) or if initialization fails for any other reason
	 * Bean都装配完成后执行初始化
	 */
	void afterPropertiesSet() throws Exception;
}
====================================================================
public interface DisposableBean {

	/**
	 * Invoked by the containing {@code BeanFactory} on destruction of a bean.
	 * @throws Exception in case of shutdown errors. Exceptions will get logged
	 * but not rethrown to allow other beans to release their resources as well.
	 */
	void destroy() throws Exception;

}

代码如下:

/**
 * @Version: 1.0.0
 * @Author: Dragon_王
 * @ClassName: BeanTest1
 * @Description: TODO描述
 * @Date: 2024/1/21 23:25
 */
public class BeanTest1 implements InitializingBean, DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("BeanTest1销毁");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("BeanTest1初始化");
    }

    public BeanTest1() {
        System.out.println("BeanTest1被创建");
    }
}
=========================

@Configuration
@ComponentScan(("com.dragon.restart1"))
public class MyConfig {
 @Bean
    public BeanTest1 beanTest1(){
        return new BeanTest1();
    }
}

在这里插入图片描述

三、@PostConstruct(初始化逻辑)和@PreDestroy(销毁逻辑)注解

  • 被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Serclet的inti()方法。
  • 被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行。
  • 被@PreDestroy修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法。被@PreDestroy修饰的方法会在destroy()方法之后运行,在Servlet被彻底卸载之前。

代码如下:

/**
 * @Version: 1.0.0
 * @Author: Dragon_王
 * @ClassName: BeanTest2
 * @Description: TODO描述
 * @Date: 2024/1/21 23:32
 */
public class BeanTest2 {
    public BeanTest2(){
        System.out.println("BeanTest2被创建");
    }

    @PostConstruct
    public void init(){
        System.out.println("BeanTest2被初始化");
    }

    @PreDestroy
    public void destory(){
        System.out.println("BeanTest2被销毁");
    }
}
========================
//
@Configuration
@ComponentScan(("com.dragon.restart1"))
public class MyConfig {
 @Bean
    public BeanTest2 beanTest2(){
        return new BeanTest2();
    }
}

在这里插入图片描述

四、BeanPostProcessor接口

BeanPostProcessor又叫Bean的后置处理器,是Spring框架中IOC容器提供的一个扩展接口,在Bean初始化的前后进行一些处理工作。

BeanPostProcessor的源码如下:

public interface BeanPostProcessor {

	/**
	 * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
	 * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
	 * or a custom init-method). The bean will already be populated with property values.
	 * The returned bean instance may be a wrapper around the original.
	 * <p>The default implementation returns the given {@code bean} as-is.
	 * @param bean the new bean instance
	 * @param beanName the name of the bean
	 * @return the bean instance to use, either the original or a wrapped one;
	 * if {@code null}, no subsequent BeanPostProcessors will be invoked
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 */
	@Nullable
	  //bean初始化方法调用前被调用
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	/**
	 * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
	 * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
	 * or a custom init-method). The bean will already be populated with property values.
	 * The returned bean instance may be a wrapper around the original.
	 * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
	 * instance and the objects created by the FactoryBean (as of Spring 2.0). The
	 * post-processor can decide whether to apply to either the FactoryBean or created
	 * objects or both through corresponding {@code bean instanceof FactoryBean} checks.
	 * <p>This callback will also be invoked after a short-circuiting triggered by a
	 * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
	 * in contrast to all other BeanPostProcessor callbacks.
	 * <p>The default implementation returns the given {@code bean} as-is.
	 * @param bean the new bean instance
	 * @param beanName the name of the bean
	 * @return the bean instance to use, either the original or a wrapped one;
	 * if {@code null}, no subsequent BeanPostProcessors will be invoked
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 * @see org.springframework.beans.factory.FactoryBean
	 */
	@Nullable
	//bean初始化方法调用后被调用
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

代码如下:

/**
 * @Version: 1.0.0
 * @Author: Dragon_王
 * @ClassName: MyBeanPostProcess
 * @Description: TODO描述
 * @Date: 2024/1/21 23:40
 */
@Component
public class MyBeanPostProcess implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
        return bean;
    }
}
============================
@Configuration
@ComponentScan(("com.dragon.restart1"))
public class MyConfig {
    @Bean
    public BeanTest1 beanTest1(){
        return new BeanTest1();
    }

    @Bean
    public BeanTest2 beanTest2(){
        return new BeanTest2();
    }
}

运行结果如下:

BeanTest1被创建
postProcessBeforeInitialization...beanTest1=>com.dragon.restart1.BeanTest1@111d5c97
BeanTest1初始化
postProcessAfterInitialization...beanTest1=>com.dragon.restart1.BeanTest1@111d5c97
BeanTest2被创建
postProcessBeforeInitialization...beanTest2=>com.dragon.restart1.BeanTest2@29c17c3d
BeanTest2被初始化
postProcessAfterInitialization...beanTest2=>com.dragon.restart1.BeanTest2@29c17c3d
IoC容器创建完成
BeanTest2被销毁
BeanTest1销毁

通过上述运行结果可以发现使用BeanPostProcessor的运行顺序为

IOC容器实例化Bean---->调用BeanPostProcessor的postProcessBeforeInitialization方法---->调用bean实例的初始化方法---->调用BeanPostProcessor的postProcessAfterInitialization方法。

总结

以上就是Bean生命周期自定义初始化和销毁的讲解。

到此这篇关于SpringBoot中Bean生命周期自定义初始化和销毁方法详解的文章就介绍到这了,更多相关SpringBoot Bean初始化和销毁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java 合并多个MP4视频文件

    Java 合并多个MP4视频文件

    这篇文章主要介绍了Java 合并多个MP4视频文件的方法,帮助大家利用Java处理视频,提高办公效率,感兴趣的朋友可以了解下
    2020-11-11
  • Java基础知识之StringWriter流的使用

    Java基础知识之StringWriter流的使用

    这篇文章主要介绍了Java基础知识之StringWriter流的使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Intellij IDEA 配置Subversion插件实现步骤详解

    Intellij IDEA 配置Subversion插件实现步骤详解

    这篇文章主要介绍了Intellij IDEA 配置Subversion插件实现步骤详解的相关资料,需要的朋友可以参考下
    2017-05-05
  • CompletableFuture 异步编排示例详解

    CompletableFuture 异步编排示例详解

    这篇文章主要为大家介绍了CompletableFuture 异步编排示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • MyBatis中的XML实现和动态SQL实现示例详解

    MyBatis中的XML实现和动态SQL实现示例详解

    这篇文章主要介绍了MyBatis中的XML实现和动态SQL实现,我们可以将XML中重复出现的内容提取出来放到sql标签中,当需要用到sql标签中的内容时,用include标签将sql标签中的内容引进来即可,感兴趣的朋友跟随小编一起看看吧
    2024-02-02
  • Java动态代理Proxy应用和底层源码详细分析

    Java动态代理Proxy应用和底层源码详细分析

    Java动态代理是一种在运行时生成代理类的机制,用于代替手动编写代理类的过程,这篇文章主要给大家介绍了关于Java动态代理Proxy应用和底层源码详细分析的相关资料,需要的朋友可以参考下
    2024-03-03
  • SpringBoot 缓存预热的实现

    SpringBoot 缓存预热的实现

    本文主要介绍了SpringBoot 缓存预热的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2007-11-11
  • Intellij IDEA 关闭和开启自动更新的提示?

    Intellij IDEA 关闭和开启自动更新的提示?

    这篇文章主要介绍了Intellij IDEA 关闭和开启自动更新的提示操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • 解决IDEA maven 项目修改代码不生效,mvn clean、install后才生效

    解决IDEA maven 项目修改代码不生效,mvn clean、install后才生效

    这篇文章主要介绍了解决IDEA maven 项目修改代码不生效,mvn clean、install后才生效的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • Java动态代理详解及实例

    Java动态代理详解及实例

    这篇文章主要介绍了Java动态代理详解及实例的相关资料,需要的朋友可以参考下
    2017-01-01

最新评论