在spring容器启动后监听事件ApplicationReadyEvent

news2024/11/29 8:52:14

概述

经常会在业务中遇到需要在项目启动后刷新/预热一些数据的要求。
常见可以监听ApplicationReadyEventContextRefreshedEvent.

但是因为常见的springboot项目都依赖的springmvc,所以实际上有2个容器,springioc容器是springmvc的父容器。

而且ContextRefreshedEvent实际中会发布多次,如果业务只需要执行一次的情况话是不太适合监听这个的。

发布多次的原因是每加载完一次context,就会执行一次ContextRefreshedEvent而且每次执行,都会再执行一次parentContextRefreshedEvent.上面提到父子容器都会触发这个事件

org.springframework.context.support.AbstractApplicationContext#publishEvent(java.lang.Object, org.springframework.core.ResolvableType)
在这里插入图片描述

只想在启动后执行一次demo

可以监听ApplicationReadyEvent事件

package com.xxx.xxx.xxx.xxx.xxx;

import cn.hutool.extra.spring.SpringUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Objects;


@Slf4j
@Component
public class xxxRefreshEventListener implements ApplicationListener<ApplicationReadyEvent> {


    @Override
    public void onApplicationEvent(ApplicationReadyEvent contextRefreshedEvent) {
        //刷新配置
        refreshTargetProperties();
    }

    private <T> T refreshObjProperties(Class<T> objClass){

        try {

            T bean = SpringUtil.getBean(objClass);

            BusinessProperties annotation = AnnotationUtils.findAnnotation(objClass, BusinessProperties.class);

            if(Objects.isNull(annotation)){
                return bean;
            }

            //配置前缀
            String prefix = annotation.prefix();

            BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());

            for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {

                String name = propertyDescriptor.getName();
                Class<?> propertyType = propertyDescriptor.getPropertyType();
                Method writeMethod = propertyDescriptor.getWriteMethod();

                //完成的config key
                String configKey = String.join(".", prefix, name);

                //获取数据
                xxx info = xxx.xxx(configKey);

                if(Objects.isNull(info )){
                    continue;
                }
                //db中存放的值
                String configValue = info.getConfigValue();

                //给属性填充值
                if(Objects.equals(propertyType, String.class)){
                    writeMethod.invoke(bean, configValue);
                }else {
                    Object propertyValue = objectMapper.readValue(configValue, propertyType);
                    writeMethod.invoke(bean, propertyValue);
                }

            }

            return bean;

        } catch (Exception e) {
            log.error("刷新配置异常,class:{}", objClass, e);
            return null;
        }

    }



}

spring关键的几个事件

  1. ContextClosedEvent spring 容器关闭事件
  2. ContextRefreshedEvent spring 容器的初始化后或者刷新完成事件;
  3. ContextStoppedEvent spring 容器停止事件
  4. ContextStartedEvent spring 容器初始化开始事件

34其实是spring生命周期相关的事件,1是整个spring容器销毁的事件。

springboot对spring容器周期事件的扩展

springboot对于spring的事件又有自己的扩展.

  1. ApplicationEnvironmentPreparedEvent 容器环境对象初始化后的事件
  2. ApplicationPreparedEvent 容器初始化前的事件,主要是在做 refresh 动作之前做触发的事件
  3. ApplicationStartedEvent 容器已经完成 refresh 动作后所触发的事件
  4. ApplicationReadyEvent 容器已经运行中的事件
  5. ApplicationFailedEvent 容器初始化失败所触发的事件
  6. ApplicationStartingEvent 容器开始时所触发的事件

触发顺序如下

ApplicationStartingEvent ->

ApplicationEnvironmentPreparedEvent -> 

ApplicationPreparedEvent ->

ContextStartedEvent -> 

ContextRefreshedEvent ->

ApplicationStartedEvent	->

ApplicationReadyEvent

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

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

相关文章

电脑上怎么录屏?2个好用的电脑录屏方法分享!

案例&#xff1a;怎么在电脑上录屏&#xff1f; 【我想分享我电脑上的操作、游戏画面给我的朋友&#xff0c;但是我不知道如何录制电脑屏幕。有没有详细的电脑录屏方法&#xff0c;在线蹲一个&#xff01;】 你是否曾经遇到这样的情况&#xff1a;需要录制电脑屏幕上的一些操…

ICLR2023 | RetMol:基于检索的可控分子生成

题目&#xff1a;Retrieval-based Controllable Molecule Generation 文章地址&#xff1a;https://openreview.net/pdf?idvDFA1tpuLvk 代码地址&#xff1a;GitHub - NVlabs/RetMol: A new retrieval-based framework for controllable molecule generation. 主题&#xf…

Netty中NioEventLoop介绍

一、Netty基本介绍 Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具&#xff0c;用以快速开发高性能、高可靠性的网络服务器和客户端程序。Netty 在保证易于开发的同时还保证了其应用的性能&#xff0c;稳定性和伸缩性。 Netty 是一…

为什么 AIGC 和大模型创业者都在安利向量数据库?

从目前 VC 的投资数据来看&#xff0c;大家对 AI 的关注点主要有三个&#xff1a;一个是基础大模型 LLM&#xff0c;第二个是具体某个场景的应用&#xff08;包括小模型&#xff09;&#xff0c;第三个就属基础模型与应用层之间的中间层了&#xff08;开发者工具和数据库等&…

AI视频成工具D-ID介绍(AI数字人常用工具)

Studio D-id&#xff0c;​一个AI视频成工具&#xff0c;用AI创作的数字人,输入人物关键词就可一键生成人物&#xff0c;上传要说的文本或音频则可以开口说话了。 关于AI语音&#xff0c;有很多选项可供选择。目前&#xff0c;Studio D-id支持多达66种语言。然后&#xff0c;您…

蚂蚁集团发布2022可持续发展报告:科研投入204.6亿,实现3年翻倍

蚂蚁集团6月1日对外发布《2022年可持续发展报告》&#xff08;下简称‘报告’&#xff09;&#xff0c;披露2022年度相关工作进展。《报告》显示&#xff0c;2022年&#xff0c;蚂蚁持续攻坚前沿和底层数字科技&#xff0c;年度科研投入204.6亿元。较2019年&#xff0c;科研投入…

19c rac部署-ssh版本太高的问题

客户有个环境需要部署19c&#xff0c;安装的oracle linux 7.9.&#xff0c;OpenSSH_7.4p1版本适合安装19c集群&#xff0c;但接到环境时&#xff0c;发现openssh已升级到9.0了&#xff0c;理由是等保需要&#xff0c;哎&#xff0c;不抱怨自己解决问题 [INS-32070] Could not r…

外贸网站建设中经常遇到的问题有哪些?

企业外贸网站是企业展示自我&#xff0c;提高品牌知名度的重要工具。在外贸网站建设中&#xff0c;我们也会遇到各种问题&#xff0c;例如&#xff0c;外贸网站设计、 SEO优化、制作周期以及质量等&#xff0c;都是我们在建设外贸网站中需要考虑的问题。 建设一个外贸网站需要多…

BFT最前线 | iOS版ChatGPT周下载突破50万人次;英伟达市值突破万亿美元创造芯片公司历史;华为开发者大会即将发布

原创 | 文 BFT机器人 AI视界 TECHNOLOGY NEWS 01 联合国教育部聚焦生成式AI 联合国科教文组织提出发展路线图 近日&#xff0c;为应对生成式人工智能技术的迅速发展&#xff0c;联合国教科文组织就此议题召开了首次全球教育部长会议。40多位部长分享了将这些工具融入教育的…

10.ES6模块化规范(关键字 import,from,as,export的用法)

导入其他模块成员要使用关键字 import &#xff0c;导出需要使用关键字 export 我们明确一个概念&#xff0c;只有js与js之间需要使用import与export&#xff0c;如果是在html中引入js是不需要用import的&#xff0c;你导入的方式是直接srcxxx.js 目录 1 默认导入导出 2 …

CMake构建Makefile深度解析:从底层原理到复杂项目

CMake构建深度解析&#xff1a;从底层原理到复杂项目实践 一、CMake构建后的项目结构解析&#xff08;Analysis of the Project Structure After CMake Build&#xff09;1.1 CMake构建后的目录结构&#xff08;Directory Structure After CMake Build&#xff09;1.2 构建生成…

分布式锁的应用场景与分布式锁实现(一):传统锁处理并发及传统锁的问题

分布式锁 代码已同步至GitCode&#xff1a;https://gitcode.net/ruozhuliufeng/distributed-project.git ​ 在应用开发中&#xff0c;特别是Web工程开发&#xff0c;通常都是并发编程&#xff0c;不是多进程就是多线程。这种场景下极其容易出现线程并发性问题&#xff0c;此时…

新能源汽车充电桩的建设及优化分析

安科瑞虞佳豪 新能源汽车充电桩在经历了几年的发展之后&#xff0c;总体情况是在持续走好的&#xff0c;并且充电桩的建设相较于以往有了很大的普及度和安全度&#xff0c;这对新能源汽车车主是一个好事&#xff0c;也鼓励了更多人选择买新能源汽车&#xff0c;但这并不是说新…

HTTP劫持是什么?如何防止网站被劫持呢?

HTTP劫持&#xff08;HTTP hijacking&#xff09;是一种网络攻击技术&#xff0c;攻击者通过各种手段截取用户的HTTP请求或响应&#xff0c;篡改其内容或重定向到恶意服务器&#xff0c;从而实施恶意活动。这种攻击可能导致用户信息泄露、身份盗窃、篡改网页内容或植入恶意代码…

鼎盛合充气泵方案——便携车载充气泵方案

便携车载充气泵主要使用在汽车轮胎充气及车胎检测上&#xff0c;是一个气压精度测量产品。充气泵方案则是通过马达运转工作而进行设计&#xff0c;利用芯片和气压传感器所做的一个智能化便携车载充气泵方案。 便携车载充气泵方案的使用范围其实不仅仅是汽车轮胎&#xff0c;它在…

Android Studio Flamingo编译项目问题记录

系统版本&#xff1a;macOS 13.4 Android Studio Flamingo | 2022.2.1 Patch 2 下载地址&#xff1a;Download Android Studio & App Tools - Android DevelopersAndroid Studio provides app builders with an integrated development environment (IDE) optimized for …

protobuf笔记

protoc -Ipb/protos -Ipb/protos/third/github.com pb/protos/custom/*.proto -I 指定需要import的gogo.proto文件路径&#xff0c; protoc查找过程为 -I后面的路径和import的路径拼接在一起。 -Ipb/protos 指定proto源文件路径-Ipb/protos/third/github.com 指定第三方proto&…

el-select如何改变样式 (:popper-append-to-body=“false“)

在使用el-select的时候&#xff0c;其样式会按照Elementui自带的默认样式为基准&#xff1b; 但往往开发过程中&#xff0c;下拉框的样式可能并不是我们想要的&#xff1b;这是我遇到过的一个案例&#xff0c;开发需求上与elementui默认样式大相径庭&#xff1b; 如何进行修改呢…

JAVA基础 - CLASSLOADER双亲委派机制?

类的生命周期 在JAVA中数据类型分为基本数据类型和引用数据类型。基本数据类型&#xff0c;由虚拟机预先定义&#xff0c;引用数据类型则需要进行类加载。 JAVA将引用数据类型分为&#xff1a;类、接口、数组和泛型参数&#xff0c;而「泛型参数」在编译时期会被擦除&#xff…

web前端 --- javascript(01)-- 介绍、变量和数据类型

JavaScript w3c&#xff1a;三层分离 结构层&#xff1a;HTML 表示层&#xff1a;CSS 行为层&#xff1a;JavaScript 介绍 &#xff08;1&#xff09;作用&#xff1a; 数据校验网页特效数据交互服务器端编程&#xff08;NodeJS&#xff09; &#xff08;2&#xff09;javas…