@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

相关文章

Java中注解与元数据示例详解

《Java中注解与元数据示例详解》Java注解和元数据是编程中重要的概念,用于描述程序元素的属性和用途,:本文主要介绍Java中注解与元数据的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参... 目录一、引言二、元数据的概念2.1 定义2.2 作用三、Java 注解的基础3.1 注解的定义3.2 内

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

JavaScript中的isTrusted属性及其应用场景详解

《JavaScript中的isTrusted属性及其应用场景详解》在现代Web开发中,JavaScript是构建交互式应用的核心语言,随着前端技术的不断发展,开发者需要处理越来越多的复杂场景,例如事件... 目录引言一、问题背景二、isTrusted 属性的来源与作用1. isTrusted 的定义2. 为

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫

使用Python实现操作mongodb详解

《使用Python实现操作mongodb详解》这篇文章主要为大家详细介绍了使用Python实现操作mongodb的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、示例二、常用指令三、遇到的问题一、示例from pymongo import MongoClientf

SQL Server使用SELECT INTO实现表备份的代码示例

《SQLServer使用SELECTINTO实现表备份的代码示例》在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误,在SQLServer中,可以使用SELECTINT... 在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误。在 SQL Server 中,可以使用 SE

使用Python合并 Excel单元格指定行列或单元格范围

《使用Python合并Excel单元格指定行列或单元格范围》合并Excel单元格是Excel数据处理和表格设计中的一项常用操作,本文将介绍如何通过Python合并Excel中的指定行列或单... 目录python Excel库安装Python合并Excel 中的指定行Python合并Excel 中的指定列P

浅析Rust多线程中如何安全的使用变量

《浅析Rust多线程中如何安全的使用变量》这篇文章主要为大家详细介绍了Rust如何在线程的闭包中安全的使用变量,包括共享变量和修改变量,文中的示例代码讲解详细,有需要的小伙伴可以参考下... 目录1. 向线程传递变量2. 多线程共享变量引用3. 多线程中修改变量4. 总结在Rust语言中,一个既引人入胜又可

一文详解Python中数据清洗与处理的常用方法

《一文详解Python中数据清洗与处理的常用方法》在数据处理与分析过程中,缺失值、重复值、异常值等问题是常见的挑战,本文总结了多种数据清洗与处理方法,文中的示例代码简洁易懂,有需要的小伙伴可以参考下... 目录缺失值处理重复值处理异常值处理数据类型转换文本清洗数据分组统计数据分箱数据标准化在数据处理与分析过