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

本文主要是介绍SpringBoot -【SmartInitializingSingleton】基础使用及应用场景,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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);@Overridepublic 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都实例化完成后,会调用该方法*/@Overridepublic 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 接口来优化应用程序的初始化过程,提高系统的性能和可靠性。

这篇关于SpringBoot -【SmartInitializingSingleton】基础使用及应用场景的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Java操作Word文档的全面指南

《Java操作Word文档的全面指南》在Java开发中,操作Word文档是常见的业务需求,广泛应用于合同生成、报表输出、通知发布、法律文书生成、病历模板填写等场景,本文将全面介绍Java操作Word文... 目录简介段落页头与页脚页码表格图片批注文本框目录图表简介Word编程最重要的类是org.apach

Python使用pip工具实现包自动更新的多种方法

《Python使用pip工具实现包自动更新的多种方法》本文深入探讨了使用Python的pip工具实现包自动更新的各种方法和技术,我们将从基础概念开始,逐步介绍手动更新方法、自动化脚本编写、结合CI/C... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Conda与Python venv虚拟环境的区别与使用方法详解

《Conda与Pythonvenv虚拟环境的区别与使用方法详解》随着Python社区的成长,虚拟环境的概念和技术也在不断发展,:本文主要介绍Conda与Pythonvenv虚拟环境的区别与使用... 目录前言一、Conda 与 python venv 的核心区别1. Conda 的特点2. Python v

Spring Boot中WebSocket常用使用方法详解

《SpringBoot中WebSocket常用使用方法详解》本文从WebSocket的基础概念出发,详细介绍了SpringBoot集成WebSocket的步骤,并重点讲解了常用的使用方法,包括简单消... 目录一、WebSocket基础概念1.1 什么是WebSocket1.2 WebSocket与HTTP

C#中Guid类使用小结

《C#中Guid类使用小结》本文主要介绍了C#中Guid类用于生成和操作128位的唯一标识符,用于数据库主键及分布式系统,支持通过NewGuid、Parse等方法生成,感兴趣的可以了解一下... 目录前言一、什么是 Guid二、生成 Guid1. 使用 Guid.NewGuid() 方法2. 从字符串创建

SpringBoot+Docker+Graylog 如何让错误自动报警

《SpringBoot+Docker+Graylog如何让错误自动报警》SpringBoot默认使用SLF4J与Logback,支持多日志级别和配置方式,可输出到控制台、文件及远程服务器,集成ELK... 目录01 Spring Boot 默认日志框架解析02 Spring Boot 日志级别详解03 Sp

Python使用python-can实现合并BLF文件

《Python使用python-can实现合并BLF文件》python-can库是Python生态中专注于CAN总线通信与数据处理的强大工具,本文将使用python-can为BLF文件合并提供高效灵活... 目录一、python-can 库:CAN 数据处理的利器二、BLF 文件合并核心代码解析1. 基础合