Spring中@PostConstruct注解的使用

1.描述

1.1 背景

        最近在做一个系统交互日志模块,要监控一个http请求,并记录请求与响应日志。项目中使用RestTemplate来发送http请求,所以打算给RestTemplate设置拦截器,来进行自定义操作。但是,只对当前类生效,不能影响到其他RestTemplate的使用。然而,在改造过程中,遇到了bean为空的情况,经排查,是因为在构造方法中使用这个bean给RestTemplate初始化拦截器操作时,bean的依赖注入还未完成,出现了空指针异常。那么是不是有一种方式,在bean依赖注入完成之后,再执行初始化呢?当然有,@PostConstruct就能解决这个问题,比较推荐这种方式。

1.2 注意事项

关于bean的使用,我们要注意:

(1)要注意bean的加载与使用顺序:如果使用该bean时,bean为空,无非就俩种情况:a:未被spring管理、b:使用该bean时,该bean的依赖注入还未完成。

(2)要将bean交给spring管理,通过依赖注入的方式去使用:如果该bean中,依赖了别的bean。那么要将该bean交给spring管理,且使用该bean时,要通过依赖注入的方式去拿,而不要去new。

2.@PostConstruct简单介绍

2.1 简介:

   @PostConstruct 是 Java 中的一个注解,用于在 Spring 框架中指定初始化方法。当一个 Bean 被实例化之后,如果该 Bean 类中存在用 @PostConstruct 注解的方法,那么该方法会在依赖注入(DI)完成后被自动调用,用于执行一些自定义的初始化操作。

2.2 @PostConstruct的作用

  • 初始化操作:在bean的依赖注入完成后,执行一些初始化操作。
  • 资源准备:比如数据库连接、文件系统访问等,需要在依赖注入完成后才能进行。
  • 状态验证:可以检查bean的依赖是否正确注入,或者做一些状态的验证。

2.3  @PostConstruct 的一些关键点:

  • @PostConstruct 注解用于在依赖注入完成后执行 Bean 的初始化逻辑。
  • 一个类中只能有一个方法用 @PostConstruct 注解。
  • 被 @PostConstruct 注解的方法不能有参数,并且返回类型必须为 void
  • 被 @PostConstruct 注解的方法通常应该是非静态的,但如果它所在类是单例模式,那么静态方法也可以被注解。

2.4 举例

(1)执行顺序:构造函数被调用——>@PostConstruct 方法被调用

import javax.annotation.PostConstruct;public class MyClass {private String message;public MyClass() {System.out.println("构造函数被调用");}@PostConstructpublic void init() {System.out.println("@PostConstruct 方法被调用");message = "Hello, World!";}public String getMessage() {return message;}
}

        在这个例子中,我们有一个名为 MyClass 的类,它有一个私有成员变量 message。我们在构造函数中打印一条消息,然后在 init 方法上使用 @PostConstruct 注解。当 Spring 容器创建 MyClass 的实例并完成依赖注入后,它会调用 init 方法来初始化 message 变量。

 (2)初始化时从文件系统加载一些配置数据:

import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;@Service
public class ConfigurationService {private String configData;@PostConstructpublic void loadConfigData() {try (BufferedReader reader = new BufferedReader(new FileReader("config.properties"))) {StringBuilder sb = new StringBuilder();String line;while ((line = reader.readLine()) != null) {sb.append(line).append("\n");}configData = sb.toString();System.out.println("Configuration data loaded.");} catch (IOException e) {throw new RuntimeException("Failed to load configuration data", e);}}public String getConfigData() {return configData;}
}

        在这个例子中,loadConfigData 方法被@PostConstruct注解所标记。当Spring IoC容器创建并完成ConfigurationService Bean的依赖注入后,这个方法就会被自动调用。 

        此外,一个类中可以有多个带有@PostConstruct注解的方法,但是通常建议只使用一个这样的方法来保持代码的清晰性和可维护性。如果需要更复杂的初始化逻辑,考虑使用InitializingBean接口或者init-method属性。

注:Spring bean的加载注入顺序大体是构造方法 -> 依赖注入 -> @PostConstruct注解的方法

3.扩展:bean的加载流程

Spring的bean加载和注入过程主要分为以下几个步骤:

  • 加载BeanDefinition

    • Spring容器通过扫描类路径、解析注解或读取XML配置文件,加载bean定义。
  • 注册BeanDefinition

    • 将加载的bean定义注册到BeanDefinitionRegistry中。
  • 创建Bean实例

    • 容器根据bean定义创建bean实例。
  • 属性填充

    • 容器会根据bean定义中的属性值,填充bean实例的属性。
  • 依赖注入

    • 容器会解析bean定义中的依赖关系,并注入相应的bean或值。
  • 调用@PostConstruct方法

    • 在依赖注入完成后,调用bean的@PostConstruct方法。
  • 初始化Bean

    • 容器会调用bean的初始化方法(如果有),比如实现了InitializingBean接口的afterPropertiesSet方法。
  • Bean准备就绪

    • 所有初始化操作完成后,bean就可以被使用了。

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

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

相关文章

Java文件IO操作知识点

关于文件 关于IO的定义 I:input输入 O:output输出,这是一套人为规定的规则,下面这个图方便我们理解输入输出的定义,统一以CPU为基准 在操作系统中其实把很多的资源都抽象成文件,我们在这里所说的文件就是"狭义"文件,平时保存在硬盘上的文件, 文件夹也是一种文件,我们…

「iOS」自定义cell与cell的复用

iOS学习 前言一:TableView协议二:cell的复用Cell的复用原理自定义cell总结 前言 UITableView是iOS开发中不可或缺的一部分,它是苹果iOS SDK提供的一种用于展示数据列表的视图控件。我们对其中的cell进行自定义,即可得到我们需要的…

Python 实现股票指标计算——BBI

BBI (Bull And Bear lndex) - 多空指标 1 公式 3日均价 3日收盘价之和 / 36日均价 6日收盘价之和 / 612日均价 12日收盘价之和 / 1224日均价 24日收盘价之和 / 24BBI (3日均价 6日均价 12日均价 24日均价) / 4 2 数据准备 我们以科创50指数 000688 为例&#xff0c…

Qt 学习第一天:安装VS和Qt

本人更换了一台新的电脑,使用联想电脑管家传输文件后没有安装VS,导致出现了以下问题: 疯狂查资料问人。弄了一个晚上加上午一个多小时之后,还是决定删掉原来的文件夹,重新下载一个 一、安装VS(Visual Stud…

算法项目报告:物流中的最短路径问题

问题描述 物流问题 有一个物流公司需要从起点A到终点B进行货物运输,在运输过程中,该公司需要途径多个不同的城市,并且在每个城市中都有一个配送站点。为了最大程度地降低运输成本和时间,该公司需要确定经过哪些配送站点&#xff…

Android:requestLayout、invalidate 和 postInvalidate 的区别

提醒:下面源码来自SDK里Android-34版本 一、requestLayout 点击查看requestLayout官网文档 1.1 requestLayout方法源码 /*** Call this when something has changed which has invalidated the* layout of this view. This will schedule a layout pass of the v…

C++ :友元类

友元类的概念和使用 (1)将类A声明为B中的friend class后,则A中所有成员函数都成为类B的友元函数了 (2)代码实战:友元类的定义和使用友元类是单向的 (3)友元类是单向的,代码实战验证 互为友元类 (1)2个类可以互为友元类,代码实战…

【LeetCode】二叉树的最大深度

目录 一、题目二、解法完整代码 一、题目 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:3 示例 2&#x…

Leetcode2160. 拆分数位后四位数字的最小和:

问题描述: 给你一个四位 正 整数 num 。请你使用 num 中的 数位 ,将 num 拆成两个新的整数 new1 和 new2 。new1 和 new2 中可以有 前导 0 ,且 num 中 所有 数位都必须使用。 比方说,给你 num 2932 ,你拥有的数位包括…

怎么剪辑音频文件?4款适合新的音频剪辑软件

是谁还不会音频剪辑?无论是个人音乐爱好者,还是专业音频工作者,我们都希望能找到一款操作简便、功能强大且稳定可靠的音频剪辑工具。今天,我就要为大家带来四款热门音频剪辑软件的体验感分享。 一、福昕音频剪辑 福昕音频剪辑是…

YOLO 模型基础入门及官方示例演示

文章目录 Github官网简介模式数据集Python 环境Conda 环境Docker 环境部署 CPU 版本官方 CLI 示例官方 Python 示例 任务目标检测姿势估计图像分类 Ultralytics HUB视频流示例 Github https://github.com/ultralytics/ultralytics 官网 https://docs.ultralytics.com/zhhttp…

【IEEE出版】第四届能源工程与电力系统国际学术会议(EEPS 2024)

第四届能源工程与电力系统国际学术会议(EEPS 2024) 2024 4th International Conference on Energy Engineering and Power Systems 重要信息 大会官网:www.iceeps.com 大会时间:2024年8月9-11日 大会…

2024年7月萤火虫航天为NASA发射8颗立方体卫星

作为美国宇航局立方体卫星发射计划的一部分,萤火虫航空航天公司于7月3日在该公司的阿尔法火箭上发射了八颗小型卫星。这枚名为“夏日噪音”的火箭于太平洋夏令时(PDT)晚上9点04分从加利福尼亚州范登堡空军基地的2号航天发射场成功升空。 立方…

解读vue3源码-响应式篇2

提示:看到我 请让我滚去学习 文章目录 vue3源码剖析reactivereactive使用proxy代理一个对象1.首先我们会走isObject(target)判断,我们reactive全家桶仅对对象类型有效(对象、数组和 Map、Set 这样的集合类型),而对 str…

【数学建模】多波束测线问题(持续更新)

多波束测线问题 问题 1建立模型覆盖宽度海水深度重叠长度重叠率 问题二问题三问题四 问题 1 与测线方向垂直的平面和海底坡面的交线构成一条与水平面夹角为 α \alpha α的斜线(如下图),称 α \alpha α为坡度。请建立多波束测深的覆盖宽度及…

Python代码,强化学习,深度学习

python代码编写,Python算法设计,强化学习优化,改进模型,训练模型,测试模型,可视化绘制,代编运行结果,交互多模型改进,预测模型,算法修改,Python包…

11.斑马纹列表 为没有文本的链接设置样式

斑马纹列表 创建一个背景色交替的条纹列表。 使用 :nth-child(odd) 或 :nth-child(even) 伪类选择器,根据元素在一组兄弟元素中的位置,对匹配的元素应用不同的 background-color。 💡 提示:你可以用它对其他 HTML 元素应用不同的样式,如 <div>、<tr>、<p&g…

利用PyTorch进行模型量化

利用PyTorch进行模型量化 目录 利用PyTorch进行模型量化 一、模型量化概述 1.为什么需要模型量化&#xff1f; 2.模型量化的挑战 二、使用PyTorch进行模型量化 1.PyTorch的量化优势 2.准备工作 3.选择要量化的模型 4.量化前的准备工作 三、PyTorch的量化工具包 1.介…

openGauss学习笔记-312 openGauss 数据迁移-MySQL迁移-迁移MySQL数据库至openGauss-概述

文章目录 openGauss学习笔记-312 openGauss 数据迁移-MySQL迁移-迁移MySQL数据库至openGauss-概述312.1 工具部署架构图 openGauss学习笔记-312 openGauss 数据迁移-MySQL迁移-迁移MySQL数据库至openGauss-概述 312.1 工具部署架构图 当前openGauss支持对MySQL迁移服务&#x…

【多任务YOLO】 A-YOLOM: You Only Look at Once for Real-Time and Generic Multi-Task

You Only Look at Once for Real-Time and Generic Multi-Task 论文链接&#xff1a;http://arxiv.org/abs/2310.01641 代码链接&#xff1a;https://github.com/JiayuanWang-JW/YOLOv8-multi-task 一、摘要 高精度、轻量级和实时响应性是实现自动驾驶的三个基本要求。本研究…