Spring从零开始学使用系列(四)之@PostConstruct和@PreDestroy注解的使用

  如果各位老爷觉得可以,请点赞收藏评论,谢谢啦!!

  文章中涉及到的图片均由AI生成

  公众号在最下方!!!

目录

1. 介绍

1.1 @PostConstruct概述

1.2 @PreDestroy概述

2. 基本用法

2.1 注册CommonAnnotationBeanPostProcessor

2.2 使用@PostConstruct注解的方法

2.3 使用@PreDestroy注解的方法

3. 使用场景

3.1 资源管理

3.2 缓存管理

3.3 初始化复杂对象

4. 注意事项

4.1 线程安全

4.2 异常处理

4.3 使用限制

4.4 调用初始化模板和方法

4.5 初始化顺序和Bean的生命周期

5. 结论

1. 介绍

        在Spring框架中,@PostConstruct和@PreDestroy注解是用于管理Bean生命周期的重要工具。这些注解提供了一种简洁的方式,在Bean的初始化和销毁阶段执行特定的逻辑,从而增强了应用程序的灵活性和可维护性。

1.1 @PostConstruct概述

        @PostConstruct注解用于在Bean初始化完成后立即执行特定的方法。这通常用于在依赖注入完成后进行一些初始化操作,例如分配资源或预填充缓存。

1.2 @PreDestroy概述

        @PreDestroy注解用于在Bean销毁之前执行特定的方法。这通常用于在Bean被销毁之前进行一些清理操作,例如释放资源或清空缓存。

        这些注解是在JSR-250规范中定义的,最初是作为Java标准库的一部分引入的。从JDK 9开始,这些注解被移除并移至Jakarta EE中。如果需要使用这些注解,需要在项目中引入jakarta.annotation-api依赖。

2. 基本用法

2.1 注册CommonAnnotationBeanPostProcessor

        要使用@PostConstruct和@PreDestroy注解,首先需要在Spring配置中注册CommonAnnotationBeanPostProcessor(老版本是不需要的,因为jdk8自带@PostConstruct注解),这样Spring才能识别并处理这些注解:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;@Configuration
public class AppConfig {@Beanpublic CommonAnnotationBeanPostProcessor commonAnnotationBeanPostProcessor() {return new CommonAnnotationBeanPostProcessor();}
}
2.2 使用@PostConstruct注解的方法

        @PostConstruct注解用于在Bean初始化完成后执行特定的方法。以下是一个示例,展示如何在Bean初始化完成后填充缓存:

import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Component;@Component
public class CachingMovieLister {@PostConstructpublic void populateMovieCache() {// 在初始化时填充电影缓存...System.out.println("Movie cache populated upon initialization");}
}
2.3 使用@PreDestroy注解的方法

        @PreDestroy注解用于在Bean销毁之前执行特定的方法。以下是一个示例,展示如何在Bean销毁之前清空缓存:

import jakarta.annotation.PreDestroy;
import org.springframework.stereotype.Component;@Component
public class CachingMovieLister {@PreDestroypublic void clearMovieCache() {// 在销毁时清空电影缓存...System.out.println("Movie cache cleared upon destruction");}
}

3. 使用场景

3.1 资源管理

        在许多应用程序中,Bean在初始化时可能需要分配一些资源(如数据库连接、文件句柄等),并在销毁时释放这些资源。@PostConstruct和@PreDestroy注解可以帮助我们在这些关键点上执行必要的操作,防止资源泄漏。

3.2 缓存管理

        在某些应用程序中,可能需要在Bean初始化时预填充缓存,并在销毁时清空缓存,以确保数据一致性和内存有效利用。

3.3 初始化复杂对象

        有时Bean依赖于其他资源进行初始化,@PostConstruct可以确保在所有依赖注入完成后执行初始化逻辑。

import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class ComplexInitializer {@Autowiredprivate SomeDependency dependency;private ComplexObject complexObject;@PostConstructpublic void init() {complexObject = new ComplexObject(dependency);System.out.println("ComplexObject initialized with dependency");}public ComplexObject getComplexObject() {return complexObject;}
}

4. 注意事项

4.1 线程安全

        在使用@PostConstruct和@PreDestroy注解的方法中,确保线程安全是非常重要的。由于Spring容器可能会在多个线程中并发地管理Bean的生命周期,方法中的代码应避免共享可变状态,或者使用同步机制保护共享资源。

4.2 异常处理

        在这些方法中处理异常是非常关键的。如果在@PostConstruct方法中抛出异常,Spring容器可能会终止Bean的初始化过程。如果在@PreDestroy方法中抛出异常,可能会导致资源泄漏。建议在这些方法中捕获并记录异常,确保应用程序的稳定性。

@PostConstruct
public void initialize() {try {// 初始化逻辑} catch (Exception e) {// 处理异常e.printStackTrace();}
}@PreDestroy
public void cleanup() {try {// 清理逻辑} catch (Exception e) {// 处理异常e.printStackTrace();}
}
4.3 使用限制

        @PostConstruct和@PreDestroy注解的方法不能是final或static的,因为Spring需要通过代理机制来管理Bean的生命周期,final或static方法无法被代理。此外,这些方法不能有参数,并且必须是无返回值的void方法。

4.4 调用初始化模板和方法

        在某些复杂的场景中,可能需要在多个Bean中复用相同的初始化或清理逻辑。可以通过定义一个模板方法,并在具体Bean中调用该模板方法来实现代码复用。

public abstract class AbstractInitializer {@PostConstructpublic void postConstruct() {init();}@PreDestroypublic void preDestroy() {destroy();}protected abstract void init();protected abstract void destroy();
}@Component
public class ConcreteInitializer extends AbstractInitializer {@Overrideprotected void init() {// 具体的初始化逻辑System.out.println("ConcreteInitializer initialized");}@Overrideprotected void destroy() {// 具体的清理逻辑System.out.println("ConcreteInitializer destroyed");}
}

        通过这种方式,可以在多个Bean中共享相同的初始化和清理逻辑,减少代码重复,提高代码的可维护性。

4.5 初始化顺序和Bean的生命周期

        在Spring中,Bean的初始化顺序可能会导致在使用@PostConstruct注解时调用其他Bean出现问题。具体来说,如果一个Bean在其@PostConstruct方法中依赖于另一个尚未初始化的Bean,就会导致初始化失败。为了避免这种情况,应该确保依赖的Bean在当前Bean之前初始化。

@Service
public class MyService {@Autowiredprivate AnotherService anotherService;@PostConstructpublic void init() {anotherService.performAction();}
}@Service
public class AnotherService {public void performAction() {System.out.println("Action performed");}
}

        在上面的示例中,如果AnotherService尚未初始化而MyService已经在其@PostConstruct方法中调用了anotherService的方法,则会导致错误。

解决方法:

  1. 确保Bean的初始化顺序:可以通过在Spring配置文件中明确指定Bean的依赖关系,确保依赖的Bean在当前Bean之前初始化。

  2. 使用@DependsOn注解:可以使用@DependsOn注解明确指定Bean的初始化顺序

  3. 在Bean的生命周期中处理依赖:了解Bean的生命周期,并在正确的生命周期阶段处理Bean的依赖关系。Spring的Bean生命周期包括实例化、属性注入、初始化和销毁等阶段。@PostConstruct方法在属性注入之后、初始化之前调用,因此应确保在此阶段所有依赖的Bean都已准备好。

5. 结论

        在Spring框架中,@PostConstruct和@PreDestroy注解为开发者提供了一种简洁而有效的方式来管理Bean的生命周期。这些注解能够确保在Bean初始化后执行必要的设置操作,并在Bean销毁前进行必要的清理操作,从而提升了应用程序的健壮性和可维护性。

        通过本文的详细介绍和示例,我们探讨了以下内容:

  1. @PostConstruct和@PreDestroy的概述:理解这些注解在Spring框架中的作用和意义。
  2. 基本用法:如何在Spring配置中注册CommonAnnotationBeanPostProcessor,以及如何在实际Bean中使用这些注解。
  3. 使用场景:通过具体示例展示了在资源管理、缓存管理和初始化复杂对象中的应用。
  4. 注意事项:强调了线程安全、异常处理、使用限制、调用初始化模板和方法、以及Bean的初始化顺序和生命周期管理的重要性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/841710.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AlexNet论文解析—ImageNet Classification with Deep Convolutional Neural Networks

AlexNet论文解析—ImageNet Classification with Deep Convolutional Neural Networks 2012 研究背景 认识数据集:ImageNet的大规模图像识别挑战赛 LSVRC-2012:ImageNet Large Scale Visual Recoanition Challenge 类别训练数据测试数据图片格式Mnist1…

通关!游戏设计之道Day15

多人游戏——越多越开心 多人游戏能给玩家带来更多的乐趣 面对面 网络对战 大型多人在线 点对点Wifi 在决定了玩家的连接方式后,接下来就要确定他们的玩法类型了。 竞争型 合作型 配合型 多人游戏模式 死亡竞赛/混战模式 团队死亡竞赛 格斗 生存 区域/…

安装mamba时报错bare_metal_version

原因:缺少cuda118的环境版本,直接安装 nvidia/label/cuda-11.8.0 可解决,代码如下: conda install -c "nvidia/label/cuda-11.8.0" cuda-nvcc

【java程序设计期末复习】chapter6 接口和实现

接口与实现 接口 为了克服Java单继承的缺点,Java使用了接口,一个类可以实现多个接口。 使用关键字interface来定义一个接口。接口的定义和类的定义很相似,分为接口的声明和接口体。 接口通过使用关键字interface来声明 interface Printab…

复习java5.26

面向对象和面向过程 面向过程:把一个任务分成一个个的步骤,当要执行这个任务的时候,只需要依次调用就行了 面向对象:把构成任务的事件构成一个个的对象,分别设计这些对象(属性和方法)、然后把…

MybatisPlus静态工具Db

前言:在开发的时候,有时Service之间也会相互调用,会出现循环依赖问题,MybatisPlus提供一个静态工具类:Db,其中的一些静态方法与IService中方法签名基本一致,也可以帮助我们实现CRUD功能。 一、Db工具类中常…

Tomcat调优参数

JVM优化 Tomcat是一个Web容器,所有的jar其实都共享Tomcat中的JVM参数,所以Tomcat的JVM参数优化至关重要。 Tomcat的JVM参数是在启动脚本中设置的,如想要设置最大堆内存和最小堆内存时: 在windows的启动脚本catalina.bat中的set &q…

深度学习面试问题总结(21)| 模型优化

本文给大家带来的百面算法工程师是深度学习模型优化面试总结,文章内总结了常见的提问问题,旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中,我们还将介绍一些常见的深度学习面试问题,并提供参考的回答及其理论基础&a…

入门五(项目介绍及登录和发布需求)

软件缺陷判定标准 项目中缺陷的管理流程 使用Excel对于缺陷进行管理 使用工具管理缺陷 一、项目背景 传智作为一个IT教育机构,拥有自己开发且实际运营的产品; 将开发和运营的技术作为授课的内容,对于学员而言学到的都是一手的真实案例和…

unordered_mapset

文章目录 Ⅰ. 使用a. unordered_mapb. unordered_set Ⅱ. 哈希表a. 闭散列:线性探测1.仿函数,2.插入,3.删除,4.查找,5.扩容 b. 开散列:哈希桶1.仿函数,2.插入,3.删除,4.查…

释放Mac潜能,选择Magic Disk Cleaner for Mac

想要让Mac运行更加流畅、性能更加出色吗?那就选择Magic Disk Cleaner for Mac吧! Magic Disk Cleaner for Mac v2.7.7激活版下载 这款软件是Mac用户的得力助手,它拥有强大的扫描和清理功能,能够迅速找出并删除硬盘上的无用文件和垃…

如何查看哪些组策略应用于你的电脑和用户帐户?这里有详细步骤

如果你希望在电脑上查看所有有效的组策略设置,以下是操作方法。 什么是Windows中的组策略 在Windows世界中,组策略为网络管理员提供了一种将特定设置分配给用户组或计算机组的方法。然后,无论何时组中的用户登录到联网的PC,或无论何时启动组中的PC,都会应用这些设置。 …

零基础学Java第二十三天之网络编程

网络编程 1. 网络编程 实现多台计算机之间实现数据的共享和传递,网络应用程序主要组成为: 网络编程IO流多线程 2. 网络编程三要素 网络通讯的模型:请求-响应,客户端-服务端 三要素:IP地址,端口&#…

头歌OpenGauss数据库-I.复杂查询第7关:李老师教的课程成绩最低的学生

任务描述 本关任务:根据提供的表和数据,查询选修“李四”老师所授课程的学生中,成绩最低的学生信息(具体输出信息请查看测试说明)及其成绩。 student表数据: s_ids_names_sex01Mia女02Riley男03Aria女04Lucas女05Oliver男06Caden男07Lily女08Jacob男course表数据: c_idc…

谷歌Google广告投放优势和注意事项!

谷歌Google作为全球最大的搜索引擎,谷歌不仅拥有庞大的用户基础,还提供了高度精准的广告投放平台,让广告主能够高效触达目标受众,实现品牌曝光、流量增长乃至销售转化的多重目标,云衔科技以专业服务助力您谷歌Google广…

【MySQL】库的基础操作

🌎库的操作 文章目录: 库的操作 创建删除数据库 数据库编码集和校验集 数据库的增删查改       数据库查找       数据库修改 备份和恢复 查看数据库连接情况 总结 前言:   数据库操作是软件开发中不可或缺的一部分&#xff0…

pod进阶—资源限制以及探针检查

一、资源限制 1.1 资源限制定义: 当定义Pod时可以选择性的为每个容器设定所需要的资源数量。最常见的可设定资源是CPU和内存大小,以及其他类型的资源。 1.2 资源限制request和limit资源约束 ①当为 Pod 中的容器指定了 request 资源时&#x…

百度文心大模型宣布两大主力模型ENIRE Speed、ENIRE Lite免费用

今日,百度智能云宣布文心大模型的两款主力模型ENIRE Speed、ENIRE Lite全面免费,即刻生效。这两款大模型今年3月发布,均支持8K和128k上下文长度。据了解,ERNIE Lite是百度自研的轻量级大语言模型,兼顾优异的模型效果与…

透视App投放效果,Xinstall助力精准分析,让每一分投入都物超所值!

在移动互联网时代,App的推广与投放成为了每一个开发者和广告主必须面对的问题。然而,如何精准地掌握投放效果,让每一分投入都物超所值,却是一个令人头疼的难题。今天,我们就来谈谈如何通过Xinstall这个专业的App全渠道…

【代码】Goc小游戏

1.口算测试 int a,b,lv1,score0,nd,yu,da,day,j,s_j0,cuo0; int main(){p.picL(1,"boy0.png").picL(2,"boy1.png").picL(3,"boy2.png").picL(4,"boy3.png");p.rr(1000,1000,14).speed(10).up().hide();p.moveTo(0,150).text("加…