@PostConstruct使用详解

2023-12-05 03:44
文章标签 使用 详解 postconstruct

本文主要是介绍@PostConstruct使用详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、简介

在Spring应用程序中启动时,有时需要在所有Bean都已加载,初始化并准备好之后执行某些自定义代码。这时,Spring提供了一个可用的方式,即使用@PostConstruct注解。这个注解用于标记一个方法,这个方法将在Bean初始化完成后被执行。而且,它是所有注解中最后一个执行的。

总结一下 @PostConstruct 的使用和特点:

  • 只有一个非静态方法能使用此注解;
  • 被注解的方法不得有任何参数;
  • 被注解的方法返回值必须为void;
  • 被注解方法不得抛出已检查异常;
  • 此方法只会被执行一次;

二、@PostConstruct作用

@PostConstruct注解用于指定一个方法在对象创建后由容器自动执行,用于完成一些初始化操作。具体作用如下

1.完成依赖注入后,执行一些需要依赖注入的操作。在构造方法执行完毕后,自动调用被@PostConstruct注解修饰的方法,可以保证对象的依赖已经被注入,可以安全地执行一些需要依赖的操作。

2.初始化一些资源。@PostConstruct注解修饰的方法可以用于初始化一些需要在对象创建后立即准备好的资源,例如数据库连接、网络连接等。

3.执行一些必要的校验操作。在对象创建后,可以使用@PostConstruct注解修饰的方法进行一些必要的校验操作,例如检查配置是否正确、检查依赖是否满足等

总之,@PostConstruct注解的作用是在对象创建后执行一些需要在对象注入完毕后进行的操作,可以用于完成初始化总之资源准备、校验等操作。

三、执行顺序

在Spring框架中,每个bean都有一个完整的生命周期,包括实例化、属性赋值、调用Bean初始化和销毁bean等阶段。@PostConstruct注解的执行时间是在初始化阶段之后。

具体而言,一个bean的生命周期的主要阶段如下:

  • 实例化(Instantiation)
  • 填充属性(Populate Properties)
  • BeanNameAware设置(BeanNameAware set)
  • BeanFactoryAware设置(BeanFactoryAware set)
  • 前置初始化(Post Process Before Initialization)
  • 初始化(Initialization)
  • 后置初始化(Post Process After Initialization)
  • 销毁(Destroy)

最后一个阶段是销毁,这不是我们关心的。我们的attention是初始化方法,其中@PostConstruct注解会在Post Process After Initialization方法后调用。

3.1 执行顺序详解

往往我们在项目启动时需要加载某个方法的时候,可以使用@Component和@PostConstruct组合将一个方法完成初始化操作,@PostConstruct 注解的方法会将在依赖注入完成之后被自动调用。

在这里插入图片描述
通过上图,可以看出该注解在整个Bean初始化中执行的顺序:@Constructor(构造方法)-> @Autowired(依赖注入)-> @PostConstruct(注解的方法)

注意: 使用此注解时会影响服务启动时间。服务启动时会扫描WEB-INF/classes的所有文件和WEB-INF/lib下的所有jar包

四、使用案例

@PostConstruct 可以在Servlet初始化之前加载一些缓存数据,如:预热数据字典,读取properties配置文件,那案例就模拟这两个场景:

4.1 数据预热

使用Redis进行的数据预热,需要项目启动以后,触发第一次调用才能生成缓存,而利用 @PostConstruct 注解能让预热数据在Bean初始化阶段完成,比Redis更早。

@Component+@PostConstruct完成预热代码如下:

@Slf4j
@Configuration
public class BeanConfiguration {@Autowiredprivate BusinessService businessService;// 模拟预热的数据private static String mysql_data;@PostConstructpublic void construct(){log.info("〓〓〓〓〓〓〓〓〓〓 Autowired 加载完成!!");mysql_data = businessService.demo5();log.info("〓〓〓〓〓〓〓〓〓〓 mysql_data = " + mysql_data);}
}

BusinessService 演示

@Slf4j
@Service
public class BusinessServiceImpl implements BusinessService {/*** 模拟从数据库查询数据的操作*/public String demo5() {log.info("〓〓〓〓〓〓〓〓〓〓 demo5:执行!!");return "mysql data";}
}

执行结果如下所示:
在这里插入图片描述

4.2 加载配置文件

@Value 注解修饰的常量不能是静态的,否则会 null,因为 static 的加载在 @Value 之前。如果不是 static 的,就要每次使用都要去加载一次 .properties 文件,有悖我们设置常量类的初衷。

现在,@PostConstruct注解可以帮我们完成预期,因为@PostConstruct的加载是在static之后的,不会出现null的情况,演示一下:

@Value获取数据,再通过@PostConstruct向static常量赋值

@Slf4j
@Component
public class GlobalConstent {@Value("${server.port}")private String port;// 模拟静态常量public static String server_port;@PostConstructpublic void construct(){log.info("〓〓〓〓〓〓〓〓〓〓 Before PostConstruct:" + server_port);server_port = port;log.info("〓〓〓〓〓〓〓〓〓〓 After PostConstruct:" + server_port);}
}

使用过程很友好,直接采用“类名·”的方式访问

@Slf4j
@RestController
@RequestMapping("/construct")
public class PostConstructController {@RequestMapping("/demo")public String demo() {log.info("〓〓〓〓〓〓〓〓〓〓 server_port:" + GlobalConstent.server_port);return "success";}
}

结果展示:加载过程都在项目成功启动之前
在这里插入图片描述

五、总结

  • @PostConstruct注解时会影响服务启动时间,服务启动时会扫描WEB-INF/classes的所有文件和WEB-INF/lib下的所有jar包;
  • @PostConstruct注解在整个Bean初始化中执行的顺序:@Constructor(构造方法)-> @Autowired(依赖注入)-> @PostConstruct(注解的方法);
  • @PostConstruct 可以在Servlet初始化之前加载一些缓存数据,如:预热数据字典,读取properties配置文件;

这篇关于@PostConstruct使用详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/456019

相关文章

使用animation.css库快速实现CSS3旋转动画效果

《使用animation.css库快速实现CSS3旋转动画效果》随着Web技术的不断发展,动画效果已经成为了网页设计中不可或缺的一部分,本文将深入探讨animation.css的工作原理,如何使用以及... 目录1. css3动画技术简介2. animation.css库介绍2.1 animation.cs

C#特性(Attributes)和反射(Reflection)详解

《C#特性(Attributes)和反射(Reflection)详解》:本文主要介绍C#特性(Attributes)和反射(Reflection),具有很好的参考价值,希望对大家有所帮助,如有错误... 目录特性特性的定义概念目的反射定义概念目的反射的主要功能包括使用反射的基本步骤特性和反射的关系总结特性

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

Python文件操作与IO流的使用方式

《Python文件操作与IO流的使用方式》:本文主要介绍Python文件操作与IO流的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、python文件操作基础1. 打开文件2. 关闭文件二、文件读写操作1.www.chinasem.cn 读取文件2. 写

详解如何在SpringBoot控制器中处理用户数据

《详解如何在SpringBoot控制器中处理用户数据》在SpringBoot应用开发中,控制器(Controller)扮演着至关重要的角色,它负责接收用户请求、处理数据并返回响应,本文将深入浅出地讲解... 目录一、获取请求参数1.1 获取查询参数1.2 获取路径参数二、处理表单提交2.1 处理表单数据三、

PyQt6中QMainWindow组件的使用详解

《PyQt6中QMainWindow组件的使用详解》QMainWindow是PyQt6中用于构建桌面应用程序的基础组件,本文主要介绍了PyQt6中QMainWindow组件的使用,具有一定的参考价值,... 目录1. QMainWindow 组php件概述2. 使用 QMainWindow3. QMainW

使用Python自动化生成PPT并结合LLM生成内容的代码解析

《使用Python自动化生成PPT并结合LLM生成内容的代码解析》PowerPoint是常用的文档工具,但手动设计和排版耗时耗力,本文将展示如何通过Python自动化提取PPT样式并生成新PPT,同时... 目录核心代码解析1. 提取 PPT 样式到 jsON关键步骤:代码片段:2. 应用 JSON 样式到

java变量内存中存储的使用方式

《java变量内存中存储的使用方式》:本文主要介绍java变量内存中存储的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍2、变量的定义3、 变量的类型4、 变量的作用域5、 内存中的存储方式总结1、介绍在 Java 中,变量是用于存储程序中数据

关于Mybatis和JDBC的使用及区别

《关于Mybatis和JDBC的使用及区别》:本文主要介绍关于Mybatis和JDBC的使用及区别,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、JDBC1.1、流程1.2、优缺点2、MyBATis2.1、执行流程2.2、使用2.3、实现方式1、XML配置文件

macOS Sequoia 15.5 发布: 改进邮件和屏幕使用时间功能

《macOSSequoia15.5发布:改进邮件和屏幕使用时间功能》经过常规Beta测试后,新的macOSSequoia15.5现已公开发布,但重要的新功能将被保留到WWDC和... MACOS Sequoia 15.5 正式发布!本次更新为 Mac 用户带来了一系列功能强化、错误修复和安全性提升,进一步增