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

相关文章

Java中对象的创建和销毁过程详析

《Java中对象的创建和销毁过程详析》:本文主要介绍Java中对象的创建和销毁过程,对象的创建过程包括类加载检查、内存分配、初始化零值内存、设置对象头和执行init方法,对象的销毁过程由垃圾回收机... 目录前言对象的创建过程1. 类加载检查2China编程. 分配内存3. 初始化零值4. 设置对象头5. 执行

SpringBoot整合easy-es的详细过程

《SpringBoot整合easy-es的详细过程》本文介绍了EasyES,一个基于Elasticsearch的ORM框架,旨在简化开发流程并提高效率,EasyES支持SpringBoot框架,并提供... 目录一、easy-es简介二、实现基于Spring Boot框架的应用程序代码1.添加相关依赖2.添

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

Python使用Pandas对比两列数据取最大值的五种方法

《Python使用Pandas对比两列数据取最大值的五种方法》本文主要介绍使用Pandas对比两列数据取最大值的五种方法,包括使用max方法、apply方法结合lambda函数、函数、clip方法、w... 目录引言一、使用max方法二、使用apply方法结合lambda函数三、使用np.maximum函数

SpringBoot中整合RabbitMQ(测试+部署上线最新完整)的过程

《SpringBoot中整合RabbitMQ(测试+部署上线最新完整)的过程》本文详细介绍了如何在虚拟机和宝塔面板中安装RabbitMQ,并使用Java代码实现消息的发送和接收,通过异步通讯,可以优化... 目录一、RabbitMQ安装二、启动RabbitMQ三、javascript编写Java代码1、引入

spring-boot-starter-thymeleaf加载外部html文件方式

《spring-boot-starter-thymeleaf加载外部html文件方式》本文介绍了在SpringMVC中使用Thymeleaf模板引擎加载外部HTML文件的方法,以及在SpringBoo... 目录1.Thymeleaf介绍2.springboot使用thymeleaf2.1.引入spring

Qt 中集成mqtt协议的使用方法

《Qt中集成mqtt协议的使用方法》文章介绍了如何在工程中引入qmqtt库,并通过声明一个单例类来暴露订阅到的主题数据,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一,引入qmqtt 库二,使用一,引入qmqtt 库我是将整个头文件/源文件都添加到了工程中进行编译,这样 跨平台

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满