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)

      • 服务提供模块
      • SpiUtil
        • 主要功能
        • 服务加载
          • loadList(serviceClass)
          • loadList(serviceClass, comparator)
          • loadMap(serviceClass)
          • loadMap(serviceClass, keyFunc)
        • 服务实例化
          • newInstance(serviceClass)
          • newInstance(serviceClass, serviceName)
        • 服务获取
          • getService(serviceClass)
          • getService(serviceClass, serviceName)
        • 服务缓存
          • clearCache()
          • clearCache(serviceClass)
        • 服务加载器获取
          • getServiceLoader(serviceClass)
          • getListServiceLoader(serviceClass)
          • getMapServiceLoader(serviceClass)
        • 注意事项
        • 总结
      • 服务提供(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
目录

SpiUtil

SpiUtil是Hutool中用于处理SPI(Service Provider Interface)的核心工具类,提供了丰富的服务加载和管理功能,简化了Java SPI的使用。

# 主要功能

  • 服务加载:加载指定接口的实现类
  • 服务缓存:缓存加载的服务,提高性能
  • 服务排序:支持服务的优先级排序
  • 服务分组:支持服务的分组管理
  • 服务实例化:实例化加载的服务
  • 服务获取:获取指定的服务

# 服务加载

# loadList(serviceClass)

加载指定接口的所有实现类到列表中。

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

# loadList(serviceClass, comparator)

加载指定接口的所有实现类,并按照指定的比较器排序。

// 按优先级加载HelloService的所有实现类(优先级高的先加载)
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

# loadMap(serviceClass)

加载指定接口的所有实现类到Map中,键为实现类的类名,值为实现类的实例。

// 加载HelloService的所有实现类到Map中
Map<String, HelloService> serviceMap = SpiUtil.loadMap(HelloService.class);
for (Map.Entry<String, HelloService> entry : serviceMap.entrySet()) {
    Console.log(entry.getKey() + ": " + entry.getValue().sayHello("Hutool"));
}
// 输出:
// cn.hutool.demo.service.HelloServiceImpl1: Hello, Hutool from ServiceImpl1
// cn.hutool.demo.service.HelloServiceImpl2: Hello, Hutool from ServiceImpl2

# loadMap(serviceClass, keyFunc)

加载指定接口的所有实现类到Map中,键由指定的函数生成,值为实现类的实例。

// 加载HelloService的所有实现类到Map中,键为实现类的优先级
Map<String, HelloService> serviceMap = SpiUtil.loadMap(HelloService.class, service -> String.valueOf(service.getPriority()));
for (Map.Entry<String, HelloService> entry : serviceMap.entrySet()) {
    Console.log(entry.getKey() + ": " + entry.getValue().sayHello("Hutool"));
}
// 输出:
// 1: Hello, Hutool from ServiceImpl1
// 2: Hello, Hutool from ServiceImpl2

# 服务实例化

# newInstance(serviceClass)

实例化指定接口的默认实现类。

// 实例化HelloService的默认实现类
HelloService service = SpiUtil.newInstance(HelloService.class);
Console.log(service.sayHello("Hutool"));
// 输出: Hello, Hutool from ServiceImpl1

# newInstance(serviceClass, serviceName)

实例化指定接口的指定实现类。

// 实例化HelloService的HelloServiceImpl2实现类
HelloService service = SpiUtil.newInstance(HelloService.class, "cn.hutool.demo.service.HelloServiceImpl2");
Console.log(service.sayHello("Hutool"));
// 输出: Hello, Hutool from ServiceImpl2

# 服务获取

# getService(serviceClass)

获取指定接口的默认实现类。

// 获取HelloService的默认实现类
HelloService service = SpiUtil.getService(HelloService.class);
Console.log(service.sayHello("Hutool"));
// 输出: Hello, Hutool from ServiceImpl1

# getService(serviceClass, serviceName)

获取指定接口的指定实现类。

// 获取HelloService的HelloServiceImpl2实现类
HelloService service = SpiUtil.getService(HelloService.class, "cn.hutool.demo.service.HelloServiceImpl2");
Console.log(service.sayHello("Hutool"));
// 输出: Hello, Hutool from ServiceImpl2

# 服务缓存

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

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

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

# clearCache()

清除所有服务缓存。

// 清除所有服务缓存
SpiUtil.clearCache();

# clearCache(serviceClass)

清除指定接口的服务缓存。

// 清除HelloService的服务缓存
SpiUtil.clearCache(HelloService.class);

# 服务加载器获取

# getServiceLoader(serviceClass)

获取指定接口的服务加载器。

// 获取HelloService的服务加载器
ServiceLoader<HelloService> serviceLoader = SpiUtil.getServiceLoader(HelloService.class);

# getListServiceLoader(serviceClass)

获取指定接口的列表服务加载器。

// 获取HelloService的列表服务加载器
ListServiceLoader<HelloService> listServiceLoader = SpiUtil.getListServiceLoader(HelloService.class);
List<HelloService> services = listServiceLoader.load();

# getMapServiceLoader(serviceClass)

获取指定接口的Map服务加载器。

// 获取HelloService的Map服务加载器
MapServiceLoader<HelloService> mapServiceLoader = SpiUtil.getMapServiceLoader(HelloService.class);
Map<String, HelloService> serviceMap = mapServiceLoader.load();

# 注意事项

  1. 服务注册:需要在META-INF/services目录下创建配置文件,文件名为接口的全限定名,文件内容为实现类的全限定名
  2. 服务实例化:服务实现类需要有公共的无参构造器,否则无法实例化
  3. 服务缓存:服务缓存会在首次调用时自动创建,后续调用会直接从缓存中获取
  4. 服务排序:可以通过比较器对加载的服务进行排序
  5. 服务分组:可以通过函数将加载的服务分组到Map中
  6. 异常处理:SpiUtil将checked异常转换为runtime异常,避免繁琐的try-catch

# 总结

SpiUtil提供了丰富的SPI操作功能,涵盖了服务加载、实例化、获取、缓存等多个方面。通过使用SpiUtil,可以大大简化Java中的SPI操作,提高开发效率。

无论是插件化开发、框架扩展还是服务发现,SpiUtil都能提供简洁高效的解决方案。其内置的服务缓存机制也提高了SPI操作的性能,适合在高并发场景下使用。

服务提供模块
服务提供(ServiceLoader)

← 服务提供模块 服务提供(ServiceLoader)→

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