Hutool Hutool
(opens new window)
🏡首页
📖指南
🎢最佳实践
💖支持
💡javaDoc (opens new window)
⏳更新记录 (opens new window)
  • 🍎gitee (opens new window)
  • 🍏github (opens new window)
(opens new window)
🏡首页
📖指南
🎢最佳实践
💖支持
💡javaDoc (opens new window)
⏳更新记录 (opens new window)
  • 🍎gitee (opens new window)
  • 🍏github (opens new window)
  • 快速入门

  • 核心(hutool-core)

    • AI(Hutool-ai)

    • 注解(annotation)

    • 数组(array)

    • JavaBean(bean)

    • 缓存(cache)

    • 类加载器(classloader)

    • 编码解码(codec)

    • 集合(collection)

    • 比较器(comparator)

    • 压缩(compress)

    • 类型转换(convert)

    • 数据(data)

    • 日期时间(date)

    • 异常(exception)

    • 函数(func)

    • IO流(io)

    • 语言特性(lang)

    • Map(map)

    • 数字数学(math)

    • 网络(net)

    • 对象池(pool)

    • 反射(reflect)

    • 正则(regex)

    • 服务提供(spi)

      • 服务提供模块
        • 模块概述
        • JDK SPI对比
          • JDK SPI的不足
          • Hutool服务提供模块的优势
        • 核心类结构
        • 模块使用场景
        • 快速开始
          • 定义服务接口
          • 实现服务接口
          • 注册服务
          • 加载服务
          • 服务缓存
        • 总结
      • SpiUtil
      • 服务提供(ServiceLoader)
    • 聚合操作(stream)

    • 字符串文本(text)

    • 并发和线程(thread)

    • 树结构(tree)

    • 工具集合(util)

    • XML操作(xml)

  • 定时任务(hutool-cron)

  • 加密(hutool-crypto)

  • 数据库(hutool-db)

  • 扩展(hutool-extra)

  • HTTP(hutool-http)

  • 日志(hutool-log)

  • 配置文件(hutool-setting)

  • JSON(hutool-json)

  • Office办公(hutool-poi)

  • 套接字(hutool-socket)

  • GUI(hutool-swing)

  • 指南
  • 核心(hutool-core)
  • 服务提供(spi)
Hutool
2026-01-03
目录

服务提供模块

服务提供模块是Hutool的核心模块之一,提供了丰富的SPI(Service Provider Interface)相关功能,简化了Java SPI的使用,使服务发现和加载更加便捷高效。

# 模块概述

SPI是Java的一种服务发现机制,允许第三方为接口提供实现,实现了接口与实现的解耦。Java内置了java.util.ServiceLoader来支持SPI,但使用起来相对复杂,需要编写大量的代码。

Hutool的服务提供模块对Java原生SPI机制进行了封装,提供了简洁易用的API,涵盖了以下功能:

  • 服务加载:加载指定接口的实现类
  • 服务管理:管理加载的服务
  • 服务缓存:缓存加载的服务,提高性能
  • 服务优先级:支持服务的优先级排序
  • 服务分组:支持服务的分组管理
  • 异常处理:提供了专门的SPI异常类

# JDK SPI对比

# JDK SPI的不足

  1. API复杂:Java原生SPI API设计较为复杂,需要编写大量的代码
  2. 服务注册繁琐:需要在META-INF/services目录下创建配置文件
  3. 缺少服务管理:没有提供服务的管理功能,如优先级、分组等
  4. 性能开销:每次使用SPI都需要重新加载服务,性能开销较大
  5. 异常处理繁琐:需要处理多种异常
  6. 缺少灵活配置:不支持灵活的服务配置

# Hutool服务提供模块的优势

  1. API简洁:提供了简洁易用的API,一个方法即可完成复杂的服务加载操作
  2. 服务管理丰富:支持服务的优先级、分组等管理功能
  3. 性能优化:内置服务缓存机制,提高性能
  4. 异常处理简化:将checked异常转换为runtime异常,避免繁琐的try-catch
  5. 配置灵活:支持灵活的服务配置
  6. 功能丰富:提供了丰富的服务加载和管理功能,满足各种需求

# 核心类结构

类名 主要功能
SpiUtil SPI工具类,提供了服务加载、管理等功能
ServiceLoader 服务加载器接口,定义了服务加载的基本操作
AbsServiceLoader 抽象服务加载器,实现了服务加载器的基本功能
ListServiceLoader 列表服务加载器,加载服务到列表中
MapServiceLoader Map服务加载器,加载服务到Map中
JdkServiceLoaderUtil JDK服务加载器工具类,封装了Java原生的ServiceLoader
SpiException SPI异常类,用于处理SPI相关的异常

# 模块使用场景

服务提供模块适用于以下场景:

  1. 插件化开发:允许第三方为应用提供插件
  2. 框架扩展:允许用户扩展框架的功能
  3. 服务发现:动态发现和加载服务
  4. 依赖注入:用于依赖注入框架
  5. 配置驱动开发:根据配置动态加载服务
  6. 模块化开发:用于模块化应用的服务管理

# 快速开始

# 定义服务接口

首先,我们需要定义一个服务接口:

// 定义服务接口
public interface HelloService {
    String sayHello(String name);
    int getPriority();
}

# 实现服务接口

然后,我们需要实现该服务接口:

// 第一个实现类
public class HelloServiceImpl1 implements HelloService {
    @Override
    public String sayHello(String name) {
        return "Hello, " + name + " from ServiceImpl1";
    }

    @Override
    public int getPriority() {
        return 1;
    }
}

// 第二个实现类
public class HelloServiceImpl2 implements HelloService {
    @Override
    public String sayHello(String name) {
        return "Hello, " + name + " from ServiceImpl2";
    }

    @Override
    public int getPriority() {
        return 2;
    }
}

# 注册服务

在META-INF/services目录下创建一个以服务接口全限定名为名称的文件,文件内容为实现类的全限定名:

cn.hutool.demo.service.HelloServiceImpl1
cn.hutool.demo.service.HelloServiceImpl2

# 加载服务

最后,我们可以使用SpiUtil来加载服务:

// 加载所有实现类
List<HelloService> services = SpiUtil.loadList(HelloService.class);
for (HelloService service : services) {
    Console.log(service.sayHello("Hutool"));
}
// 输出:
// Hello, Hutool from ServiceImpl1
// Hello, Hutool from ServiceImpl2

// 按优先级加载实现类(优先级高的先加载)
List<HelloService> servicesByPriority = SpiUtil.loadList(HelloService.class,
    (o1, o2) -> Integer.compare(o2.getPriority(), o1.getPriority()));
for (HelloService service : servicesByPriority) {
    Console.log(service.sayHello("Hutool"));
}
// 输出:
// Hello, Hutool from ServiceImpl2
// Hello, Hutool from ServiceImpl1

# 服务缓存

SpiUtil内置了服务缓存机制,会缓存加载的服务,提高性能。缓存会在首次调用时自动创建,后续调用会直接从缓存中获取,避免重复的服务加载。

// 第一次调用,会加载服务并缓存
List<HelloService> services1 = SpiUtil.loadList(HelloService.class);

// 第二次调用,会直接从缓存中获取
List<HelloService> services2 = SpiUtil.loadList(HelloService.class);

# 总结

服务提供模块是Hutool的核心模块之一,提供了丰富的SPI相关功能,简化了Java SPI的使用。通过使用服务提供模块,可以大大减少SPI操作的代码量,提高开发效率。

无论是插件化开发、框架扩展还是服务发现,服务提供模块都能提供简洁高效的解决方案。其内置的服务管理功能和缓存机制也提高了开发效率和性能。

接下来,我们将详细介绍服务提供模块中的核心工具类SpiUtil,帮助大家更好地理解和使用这些工具类。

RegexPool 正则表达式池
SpiUtil

← RegexPool 正则表达式池 SpiUtil→

Theme by Vdoing | Copyright © 2025-2026 Hutool | Apache-2.0
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式