SpringBoot日常:Spring之@PostConstruct解析

news2024/11/16 13:28:14

简介

spring的Bean在创建的时候会进行初始化,而初始化过程会解析出@PostConstruct注解的方法,并反射调用该方法。
@PostConstruct 的使用和特点

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

源码分析

在Bean创建完成后,进行初始化的过程中,主要包含了初始化的前置、后置处理,以及初始化方法的调用。@PostConstruct注解将在applyBeanPostProcessorsBeforeInitialization这个前置处理

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	//遍历了在spring启动过程中被注册的BeanPostProcessor接口,
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		//调用其前置方法。
		Object current = processor.postProcessBeforeInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

@PostConstruct注解是会被一个专门的BeanPostProcessor接口的具体实现类来处理的InitDestroyAnnotationBeanPostProcessor

//org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	// 元数据解析  注解的初始化方法也会在这里被找到
	LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
	try {
		// 触发初始化方法
		metadata.invokeInitMethods(bean, beanName);
	}
	catch (InvocationTargetException ex) {
		throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
	}
	catch (Throwable ex) {
		throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
	}
	return bean;
}
public void invokeInitMethods(Object target, String beanName) throws Throwable {
	Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
	Collection<LifecycleElement> initMethodsToIterate =
			(checkedInitMethods != null ? checkedInitMethods : this.initMethods);
	if (!initMethodsToIterate.isEmpty()) {
		for (LifecycleElement element : initMethodsToIterate) {
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod());
			}
			//  调用
			element.invoke(target);
		}
	}
}

注意:在CommonAnnotationBeanPostProcessor这个后置处理器的构造方法中,@PostConstruct注解被设置为了initAnnotationType的值

//org.springframework.context.annotation.CommonAnnotationBeanPostProcessor

public CommonAnnotationBeanPostProcessor() {
	setOrder(Ordered.LOWEST_PRECEDENCE - 3);
	setInitAnnotationType(PostConstruct.class);
	setDestroyAnnotationType(PreDestroy.class);
	ignoreResourceType("javax.xml.ws.WebServiceContext");

	// java.naming module present on JDK 9+?
	if (jndiPresent) {
		this.jndiFactory = new SimpleJndiBeanFactory();
	}
}

应用场景

@PostConstruct不算一个扩展点,但是也有比较实用的应用场景,主要在Servlet初始化之前加载一些缓存数据,比如

  • 数据字典,
  • 读取properties配置文件

代码示例

@Component
@Slf4j
public class TagPostConstruct {

    @Autowired
    private TestAutowired testAutowired;

    public TagPostConstruct(){
        log.info("TagPostConstruct构造方法------run");
    }

    @PostConstruct
    public void myPostConstruct() {
        log.info("PostConstruct------run");
    }
}

@Slf4j
@Component
public class TestAutowired {

    public TestAutowired(){
        log.info("TestAutowired构造方法------run");
    }
}

运行示例

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

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

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

相关文章

Marin说PCB之TP测试的Layout设计要求

提及到TP点这个器件想必诸位道友们肯定不会陌生吧&#xff0c;我们的单板在量产之前都是需要做很多测试的&#xff0c;一般在产品研发的A版本和B版本的时候都是需要在单板上加上这个器件的。小编我最近在做一个改板&#xff0c;项目组为了降本增效&#xff0c;把单板的尺寸缩小…

Git 忽略已经提交的文件

对于未提交过的文件直接用ignore文件即可,不再赘述 对于已经提交过的文件,但是实际上不需要的,可以用git rm --cached命令 比如下图这个 .vsconfig被我误提交了或者忘了在ignore里添加了 但是我实际上不想要这个文件,那么在项目根目录打开git bash ,输入 git rm --cached .vsc…

LMDeploy 量化部署

创建环境和模型 conda create -n lmdeploy python3.10 -y conda activate lmdeploy conda install pytorch2.1.2 torchvision0.16.2 torchaudio2.1.2 pytorch-cuda12.1 -c pytorch -c nvidia -y pip install timm1.0.8 openai1.40.3 lmdeploy[all]0.5.3 mkdir /root/models …

[海思3403] 初始配置

虚拟机和板卡桥接 首先将虚拟机设置为桥接模式 板卡用网线和PC机连接&#xff0c;PC机用VMware打开Ubuntu虚拟机 点击虚拟网络编辑器&#xff0c;点击更改设置

爬取数据时,如何避免违法问题

目录 如何判断一个网站是否有明确禁止爬取数据&#xff1f; 如何处理爬取到的个人隐私数据以符合数据保护法规&#xff1f; 在爬取数据时&#xff0c;如何避免给目标网站带来过多的流量压力&#xff1f; 思维导图 在爬取数据时&#xff0c;避免违法问题的关键在于确保遵守相…

智慧工地:物联网技术和传感器技术的应用

随着科技的不断发展&#xff0c;物联网技术在各个领域得到了广泛的应用。在建筑行业中&#xff0c;智慧工地系统中物联网应用正逐渐成为一种趋势。本文将深入探讨智慧工地系统中物联网和传感器技术应用的内容。 物联网&#xff08;IoT&#xff09;和传感器技术在智慧工地中扮演…

养宠家庭除浮毛必入!希喂、安德迈、有哈宠物空气净化器真实对比

养过猫咪的铲屎官应该都体验过被换毛季支配的恐惧吧&#xff0c;夏天布偶的掉毛量已经全新升级了&#xff01;不仅是物体表面&#xff0c;连空气中都夹杂着浮毛&#xff0c;早上起来鼻子里偶尔都能发现它们的身影。长期生活在这样的环境中&#xff0c;肯定会对身体健康造成损害…

Spring数据访问层管理 ▎集成MyBatis ▎AOP ▎事务管理 ▎SpringWeb配置

前言: 在现代软件开发中&#xff0c;数据访问层的管理至关重要。Spring框架凭借其模块化结构和易用性&#xff0c;成为Java EE开发的首选。本文将探讨Spring在数据访问层的管理、MyBatis的集成、面向切面编程&#xff08;AOP&#xff09;、事务管理和Spring Web配置。 数据访…

【Material-UI】Select组件中的Native Select与TextField详解

文章目录 一、Select 组件概述1. 组件介绍2. Native Select 与 TextField 的区别 二、Native Select 组件详解1. 何为 Native Select2. Native Select 的基本用法3. Native Select 的优势与适用场景4. 自定义 Native Select 的样式 三、TextField 与 Select 的结合使用1. TextF…

BMS(三)

BAT (Pin 1): 连接到电池组的最高电压端&#xff08;CELL5&#xff09;。芯片通过该引脚监控整个电池组的总电压。 VC5 (Pin 2): 连接到第五节电池的正极&#xff0c;用于监控第五节电池的电压。 VC4 (Pin 3): 连接到第四节电池的正极&#xff0c;用于监控第四节电池的电压。 V…

【Datawhale X 李宏毅苹果书 AI夏令营】《深度学习详解》Task2 打卡

文章目录 前言学习目标一、线性模型二、分段线性曲线总结 前言 本文是【Datawhale X 李宏毅苹果书 AI夏令营】的Task2学习笔记打卡。 学习目标 李宏毅老师对应视频课程&#xff1a;https://www.bilibili.com/video/BV1JA411c7VT?p3 《深度学习详解》第一章主要介绍了深度学习…

Windows中Jupyter notebook设置默认目录

起因是我想白嫖实验室的显卡&#xff0c;就想在实验室电脑上安一个jupyter&#xff0c;就有了一系列问题 默认位置是这样的 方法一&#xff1a;配置文件 step1&#xff1a;生成jupyter配置文件 打开cmd&#xff0c;输入【jupyter notebook --generate-config】&#xff0c;输…

基于yolov8的行人跌倒检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv8的行人跌倒检测系统是利用先进的深度学习技术&#xff0c;特别是YOLOv8模型&#xff0c;来实现高效、准确的行人跌倒行为检测。YOLOv8作为YOLO系列的最新版本&#xff0c;通过改进的网络架构和训练策略&#xff0c;在保持高检测速度的同时&#xff0c;…

opencv实战项目十七:透射变换仪表表盘校正

文章目录 前言一、透射变换介绍&#xff1a;二、opencv实现2.1 cv2.getPerspectiveTransform()2.2 cv2.warpPerspective&#xff08;&#xff09; 三&#xff0c;代码实现&#xff1a;四&#xff0c;矫正效果&#xff1a; 前言 在这个信息化时代&#xff0c;图像处理技术在众多…

Python 利用rasterio库进行坐标转换

这是一篇必应上找的手册上的文章&#xff0c;特此记录 参考链接&#xff1a; 原文 参考链接2 影像中的RPC信息 目录 1、仿射变换矩阵转换2、使用控制点转换3、使用RPC进行坐标点转换 1、仿射变换矩阵转换 上面说的利用仿射转换矩阵进行转换&#xff0c;一些注意事项可以参考原文…

TQRFSOC开发板47DR LWIP自环测试

本例程基于RFSOC 47DR开发板实现LWIP自环通讯测试。使用开发板的网口与电脑或路由器等设备连接&#xff0c;使开发板与电脑在同一局域网内&#xff0c;使用telnet工具连接开发板&#xff0c;进行LWIP自环测试。 LWIP自环测试工程在Hello World项目上进行修改&#xff0c;首先打…

eclipse 配置 ABAP 连接操作手册

参考 GUI配置 按选择是否勾选single sign-on的方式&#xff0c;选择是否输入密码 点击NEXT 点击完成。

sqli-labs靶场通关攻略(46-50关)

第46关 &#xff08;ORDER BY数字型注入&#xff09; 输入?sort1 修改参数为2试一下 看到按照字母顺序进行了排序&#xff0c;所以它便是一个使用了order by语句进行排序的查询的一种查询输出方式 1出现报错&#xff0c;那么我们使用报错注入 查库 ?sort1 and updatexml(1,…

go.uber.org/ratelimit 源码分析

go.uber.org/ratelimit 源码分析 go 提供了一用来接口限流的包。其中"go.uber.org/ratelimit" 包正是基于漏桶算法实现的。 使用方式&#xff1a; 通过 ratelimit.New 创建限流器对象&#xff0c;参数为每秒允许的请求数&#xff08;RPS&#xff09;。使用 Take()…

8.29T2 国际象棋(构造:棋盘拆分成小方阵)

http://cplusoj.com/d/senior/p/NODSX2303B 暴力显然&#xff0c;因为肯定是从奇点到偶点&#xff0c;所以二分图匹配一下就好 首先我们手模一下&#xff0c;比如&#xff08;11,11&#xff09;&#xff0c;我们可以手模出一个情况&#xff0c;也就是DInic跑出来的情况&#…