SpringBoot -【SmartInitializingSingleton】基础使用及应用场景

news2024/12/24 0:52:11

SmartInitializingSingleton

在继续深入探讨 SmartInitializingSingleton接口之前,让我们先了解一下 Spring Framework 的基本概念和背景。Spring Framework 是一个开源的 JavaEE(Java Enterprise Edition)全栈(full-stack)轻量级应用程序框架,用于开发企业级应用程序。它提供了广泛的基础设施支持和丰富的特性,以简化企业级应用程序的开发。

1. Spring Framework 概述

Spring Framework 的核心特性包括:

1.1 控制反转(Inversion of Control,IoC)

Spring 使用控制反转(IoC)原则来管理对象之间的依赖关系。在传统的 Java 开发中,对象的创建和依赖关系通常由程序员自己管理,而在 Spring 中,容器负责创建对象并将它们装配起来。这种方式将对象之间的依赖关系从代码中解耦,提高了代码的灵活性和可维护性。

1.2 依赖注入(Dependency Injection,DI)

依赖注入是控制反转的一种实现方式,它通过将对象的依赖关系注入到对象本身,来实现对象之间的解耦。Spring 使用依赖注入来管理对象之间的依赖关系,通过配置文件或者注解来描述对象之间的关系,然后由 Spring 容器负责将依赖关系注入到对象中。

1.3 切面编程(Aspect-Oriented Programming,AOP)

切面编程是一种用于将横切关注点(cross-cutting concerns)从应用程序的核心逻辑中分离出来的编程范式。在 Spring 中,通过 AOP 可以实现诸如日志记录、性能监控、事务管理等与业务逻辑无关的功能,从而提高代码的模块化和可重用性。

1.4 面向接口编程(Interface-Based Programming)

Spring 鼓励使用面向接口编程的方式来开发应用程序,这样可以提高代码的灵活性和可扩展性。Spring 的许多特性都是基于接口实现的,如依赖注入、AOP 等,这使得开发者可以很容易地实现自己的定制功能。

1.5 配置简化

Spring 提供了多种配置方式,包括基于 XML 的配置、基于注解的配置和基于 Java 的配置,使得开发者可以根据自己的习惯和项目的需求选择合适的配置方式,并且可以灵活地切换配置方式而不影响应用程序的正常运行。

1.6 模块化设计

Spring Framework 被设计为一组相互独立、松耦合的模块,每个模块都提供特定的功能,如核心容器、数据访问/集成、Web 开发、AOP 支持等。开发者可以根据自己的需求选择需要的模块,而不必引入整个框架。

2. SmartInitializingSingleton 接口介绍

现在让我们转向本文的重点:SmartInitializingSingleton 接口。在 Spring Framework 中,SmartInitializingSingleton 是一个特殊的接口,用于在 Spring 容器中所有单例 Bean 初始化完成后执行一些自定义的初始化逻辑。它允许开发者在所有单例 Bean 都已经准备就绪后执行一些特定的操作,这对于需要在应用程序启动时进行一些额外的初始化工作的场景非常有用。

2.1 SmartInitializingSingleton 接口定义

javaCopy codepublic interface SmartInitializingSingleton {
    void afterSingletonsInstantiated();
}

SmartInitializingSingleton 接口非常简单,只有一个方法:afterSingletonsInstantiated()。在 Spring 容器中所有的单例 Bean 都初始化完成之后,Spring 容器会回调实现了 SmartInitializingSingleton 接口的类的 afterSingletonsInstantiated() 方法,从而触发相应的初始化逻辑。

2.2 使用示例

让我们通过一个简单的示例来说明如何使用 SmartInitializingSingleton 接口。假设我们有一个需要在所有单例 Bean 初始化完成后执行初始化逻辑的场景,我们可以定义一个实现了 SmartInitializingSingleton 接口的类,然后在其中实现 afterSingletonsInstantiated() 方法来执行相应的初始化逻辑。

javaCopy code@Component
public class MyInitializer implements SmartInitializingSingleton {

    private static final Logger logger = LoggerFactory.getLogger(MyInitializer.class);

    @Override
    public void afterSingletonsInstantiated() {
        // 执行初始化逻辑
        logger.info("All singleton beans have been instantiated.");
        // 可以在这里执行一些初始化操作,如加载配置文件、初始化缓存等
    }
}

在上面的示例中,我们定义了一个名为 MyInitializer 的类,它实现了SmartInitializingSingleton 接口,并重写了 afterSingletonsInstantiated() 方法。在这个方法中,我们可以执行任何需要在所有单例 Bean 初始化完成后执行的初始化逻辑。

3.案例

3.1 初始化缓存信息

在项目开发中,用户经常会浏览各种商品,如服装、家居用品、电子设备等。为了提高用户体验和系统性能,平台决定引入缓存机制来存储商品信息,以减少对数据库的频繁访问。在系统启动时,需要初始化商品信息的缓存(从数据库中进行查询),以便在用户请求时快速响应。为了实现这一目标,我们将使用 Spring 框架的 SmartInitializingSingleton 接口来在所有单例 Bean 初始化完成后执行初始化缓存的操作。

3.1.2 创建商品实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {
	private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

	/**
	 * 商品id唯一
	 */
	private String goodId;

	/**
	 * 商品名称
	 */
	private String goodName;

	/**
	 * 商品价格
	 */
	private BigDecimal price;


	public String toString(Product product){
		StringBuffer sb = new StringBuffer();
		sb.append("商品id:").append(product.getGoodId()).append("商品名称:").append(product.getGoodName()).append("商品价格:").append(product.getPrice());
		return sb.toString();
	}
}

3.1.3 编写商品缓存类

/**
 *
 * 商品缓存类型
 * @author 13723
 * @version 1.0
 * 2024/2/24 12:49
 */
@Component
public class ProductCache implements SmartInitializingSingleton {
	private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

	/**
	 * 商品缓存Map
	 */
	private static final Map<String,Product> goodMap = new HashMap<>();


	/**
	 * 添加商品到缓存
	 * @param product
	 */
	public void addGood(Product product){
		// 添加商品到缓存
		goodMap.put(product.getGoodId(),product);

	}

	/**
	 * 根据商品id获取商品
	 */
	public Product getGoods(String goodId){
		Product product = goodMap.get(goodId);
		if (product == null){
			logger.error("未查询到商品!");
		}
		return product;
	}

	public void initializingGoods(){
		// 初始化商品信息
		Product product1 = new Product("1", "手机", new BigDecimal("111.23"));
		Product product2 = new Product("2", "笔记本", new BigDecimal("1121.23"));
		Product product3 = new Product("3", "相机", new BigDecimal("3331.23"));
		Product product4 = new Product("4", "游戏机", new BigDecimal("12111.23"));

		addGood(product1);
		addGood(product2);
		addGood(product3);
		addGood(product4);
		logger.error("=========== 初始化商品信息完成 ===========");
	}

	/**
	 * 在项目启动时,所有的单例bean都实例化完成后,会调用该方法
	 */
	@Override
	public void afterSingletonsInstantiated() {
		// 初始化商品信息
		initializingGoods();
	}
}

3.1.4 编写测试类

@Test
@DisplayName("测试SmartInitializingSingleton Bean加载")
public void testSmartInitializingSingleton(){
    // 测试SmartInitializingSingleton Bean加载
    logger.error("商品信息未:{}",productCache.getGoods("1"));
    logger.error("商品信息未:{}",productCache.getGoods("2"));
    logger.error("商品信息未:{}",productCache.getGoods("3"));
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. SmartInitializingSingleton 的使用场景

SmartInitializingSingleton 接口提供了一种灵活的机制来处理在 Spring 容器启动时需要执行的初始化逻辑。它适用于许多场景,包括但不限于:

4.1 加载配置信息

在应用程序启动时,可能需要加载一些配置信息,如数据库连接信息、系统参数等。SmartInitializingSingleton 接口可以用来执行这些初始化操作,确保在所有单例 Bean 初始化完成之后再加载配置信息。

4.2 初始化缓存

在应用程序启动时,可以使用 SmartInitializingSingleton 接口来初始化缓存,以提高系统的性能和响应速度。通过在所有单例 Bean 初始化完成后执行初始化缓存的操作,可以确保缓存数据已经准备就绪,从而避免了在系统运行时动态加载数据造成的性能损耗。

4.3. 执行定时任务

在某些情况下,可能需要在应用程序启动时执行一些定时任务,如数据同步、数据清理等。SmartInitializingSingleton 接口可以用来执行这些定时任务,以确保它们在所有单例 Bean 初始化完成之后立即执行。

总结

在本文中,我们介绍了 Spring Framework 的核心特性和背景,并深入探讨了 SmartInitializingSingleton 接口。通过实现 SmartInitializingSingleton 接口,开发者可以在 Spring 容器中所有单例 Bean 初始化完成后执行一些自定义的初始化逻辑,从而提高应用程序的灵活性和可维护性。我们还介绍了 SmartInitializingSingleton 接口的使用示例和常见的使用场景,希望能够帮助开发者更好地理解和应用这一特性。

总的来说,SmartInitializingSingleton 接口为 Spring 应用程序提供了一个强大而灵活的初始化机制,可以满足各种复杂应用程序的初始化需求,是 Spring Framework 中的一个重要组成部分。开发者可以根据自己的实际需求,合理地使用 SmartInitializingSingleton 接口来优化应用程序的初始化过程,提高系统的性能和可靠性。

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

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

相关文章

javaEE图书馆自习室订座系统信用springmvc+springboot+mybatis

研究的内容是设计和实现图书馆自习室系统&#xff0c;便捷广大师生对自习室的使用&#xff0c;协助图书馆自习室管理。在设计过程中&#xff0c;系统的用户角色和权限分配如下&#xff1a; &#xff08;1&#xff09;馆长 用户管理&#xff1a;拥有自习室管理员、普通用户的所有…

29. 【Linux教程】Linux 用户介绍

本小节介绍 Linux 用户的基础知识&#xff0c;了解 Linux 系统中有哪些用户&#xff0c;如何查看当前 Linux 系统中有哪些用户&#xff0c;每一个 Linux 用户的权限取决于这些账号登录时获取到的权限。 1. Linux 用户类型 Linux 系统是一个多用户多任务的操作系统&#xff0c;…

前后端分离PHP+vue+mysql城市轨道交通线路公交查询系统

医院、厕所、药店、派出所、学校、营业厅、快递、银行 开发语言&#xff1a;php 后端框架&#xff1a;Thinkphp 前端框架&#xff1a;vue.js 服务器&#xff1a;apache 数据库&#xff1a;mysql 运行环境:phpstudy/wamp/xammp等 A.美食 快餐、中餐、自助餐、火锅、烧烤、奶…

【前端素材】推荐优质后台管理系统Follow平台模板(附源码)

一、需求分析 当我们从多个层次来详细分析后台管理系统时&#xff0c;可以将其功能和定义进一步细分&#xff0c;以便更好地理解其在不同方面的作用和实际运作。 1. 结构层次 在结构层次上&#xff0c;后台管理系统可以分为以下几个部分&#xff1a; a. 核心功能模块&#…

目标检测新SOTA:YOLOv9 问世,新架构让传统卷积重焕生机

在目标检测领域&#xff0c;YOLOv9 实现了一代更比一代强&#xff0c;利用新架构和方法让传统卷积在参数利用率方面胜过了深度卷积。 继 2023 年 1 月 YOLOv8 正式发布一年多以后&#xff0c;YOLOv9 终于来了&#xff01; 我们知道&#xff0c;YOLO 是一种基于图像全局信息进行…

【大厂AI课学习笔记NO.50】2.3深度学习开发任务实例(3)任务背景与目标

我们经常在做项目的时候&#xff0c;觉得分析背景和目标是浪费时间&#xff0c;觉得不过如此。 其实目标梳理特别重要&#xff0c;直接决定你数据的需求分析&#xff0c;模型的选择&#xff0c;决定你交付的质量。 人工智能项目也和其他项目一样&#xff0c;不要想当然&#…

js实现鼠标拖拽改变div大小的同时另一个div宽度也变化

实现效果如下图所示 源码如下 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>.box {width: 100%;height: 300px; display: flex;}/*左侧div样式*/.left {width: calc(30% - 5px); /*左侧初始…

SQL注入漏洞解析

什么是SQL注入 原理&#xff1a; SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严&#xff0c;攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句&#xff0c;在管理员不知情的情况下实现非法操作&#xff0c;以此来实现欺骗数据库服…

贪心/树形dp

思路&#xff1a; 因为如果红色节点的子树中如果有红色节点的话&#xff0c;那么该子树对其不会造成影响&#xff0c;不用考虑&#xff0c;因此我们在考虑每个红色节点时&#xff0c;不考虑其红色子树。那么如图&#xff0c;对每个红色节点答案有贡献的就是其所有非红色子节点…

入侵检测系统的设计与实现

入侵检测系统&#xff08;Intrusion Detection System&#xff0c;简称IDS&#xff09;是一种能够监视网络或计算机系统活动的安全工具&#xff0c;旨在识别并响应可能的恶意行为或安全事件。这些事件可能包括未经授权的访问、恶意软件、拒绝服务攻击等。入侵检测系统通过不同的…

刘雯井柏然植物园漫步,情侣裙超养眼,甜蜜穿搭亮了。

♥ 为方便您进行讨论和分享&#xff0c;同时也为能带给您不一样的参与感。请您在阅读本文之前&#xff0c;点击一下“关注”&#xff0c;非常感谢您的支持&#xff01; 文 |猴哥聊娱乐 编 辑|徐 婷 校 对|侯欢庭 刘雯井柏然漫步永州植物园&#xff0c;情侣裙惊艳亮相&#x…

算法沉淀——记忆化搜索(leetcode真题剖析)

算法沉淀——记忆化搜索 01.斐波那契数02.不同路径03.最长递增子序列04.猜数字大小 II05.矩阵中的最长递增路径 记忆化搜索算法&#xff08;Memoization&#xff09;是一种通过存储已经计算过的结果来避免重复计算的优化技术&#xff0c;通常应用于递归算法中。这种技术旨在提高…

Jenkins中Publish Over SSH插件使用(1)

SSH插件 前言Publish Over SSH插件是jenkins里面必不可少的插件之一&#xff0c;主要的功能有两个把jenkins服务器上的文件&#xff0c;传输到远程nginx&#xff0c; 远程执行shell命令和脚本。 1. SSH插件下载与配置 1.1 下载Publish over SSH插件 系统管理—》管理插件 …

stm32单片机的智能手环-心率-步数-距离-体温-蓝牙监控

一.硬件方案 随着社会的发展&#xff0c;人们的物质生活水平日渐提高&#xff0c;人们也越来越关注自己的健康。智能手环作为一种测量仪器&#xff0c;可以计算行走的步数和消耗的能量&#xff0c;所以人们可以定量的制定运动方案来健身&#xff0c;并根据运行情况来分析人体的…

javaweb day3 day4 day5

js 引入方式 写法 基础语法 写法 变量 写法 数据类型 运算符 与java相同 会判断类型是否相同 循环控制语句 和java相同 函数&#xff08;方法&#xff09; 写法 Array数组 写法 string字符串 写法 js自定义对象 写法 JSON 写法 BOM window 写法 location 写法 DOM 案例…

蓝桥杯DP算法——区间DP(C++)

根据题意要求的是将石子合并的最小权值&#xff0c;我们可以根据DP思想使用二维数组f[i,j]来存放所有从第i堆石子到第j堆石子合并成一堆石子的合并方式。 然后由第二个图所示&#xff0c;我们可以将i到j区间分成两个区间&#xff0c;因为将i到j合并成一个区间的前一步一定是合…

C++中的STL数据结构

内容来自&#xff1a;代码随想录&#xff1a;哈希表理论基础 1.常见的三种哈希结构 当我们想使用哈希法来解决问题的时候&#xff0c;我们一般会选择如下三种数据结构 数组 set &#xff08;集合&#xff09; map(映射) 在C中&#xff0c;set 和 map 分别提供以下三种数据结构…

利用LaTex批量将eps转pdf、png转eps、eps转png、eps转svg、pdf转eps

1、eps转pdf 直接使用epstopdf命令&#xff08;texlive、mitex自带&#xff09;。 在cmd中进入到eps矢量图片的目录&#xff0c;使用下面的命令&#xff1a; for %f in (*.eps) do epstopdf "%f" 下面是plt保存eps代码&#xff1a; import matplotlib.pyplot as…

win11修改网络算法为BBR2_提升网络环境质量

Win11 BBR2 是Google开发的一种高效的网络拥塞控制算法&#xff0c;玩 Linux 的朋友应该对它还有锐速不陌生。相比Windows默认使用的 CUBIC 算法&#xff0c;BBR2 在网络吞吐量、延迟、全局性能等方面都有一定优势。 如果你日常网络经常丢包或者高延迟可以尝试切换为BBR2算法。…