本文目录导读:

我来为您提供一个完整的 Java ServiceLoader 案例,包括服务接口、多个实现和实际使用示例。
项目结构
service-loader-demo/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/
│ │ │ ├── service/
│ │ │ │ ├── MessageService.java (接口)
│ │ │ │ └── impl/
│ │ │ │ ├── EmailServiceImpl.java
│ │ │ │ └── SmsServiceImpl.java
│ │ │ └── Main.java (测试类)
│ │ └── resources/
│ │ └── META-INF/
│ │ └── services/
│ │ └── com.example.service.MessageService
核心代码
1 服务接口
package com.example.service;
/**
* 消息服务接口
*/
public interface MessageService {
/**
* 发送消息
* @param to 接收人
* @param content 消息内容
* @return 发送结果
*/
String sendMessage(String to, String content);
/**
* 获取服务类型
* @return 服务类型名称
*/
String getServiceType();
}
2 具体实现类
EmailServiceImpl.java:
package com.example.service.impl;
import com.example.service.MessageService;
/**
* 邮件服务实现
*/
public class EmailServiceImpl implements MessageService {
@Override
public String sendMessage(String to, String content) {
System.out.println("📧 [邮件服务] 发送邮件到: " + to);
System.out.println(" 邮件内容: " + content);
return "邮件发送成功";
}
@Override
public String getServiceType() {
return "邮件";
}
}
SmsServiceImpl.java:
package com.example.service.impl;
import com.example.service.MessageService;
/**
* 短信服务实现
*/
public class SmsServiceImpl implements MessageService {
@Override
public String sendMessage(String to, String content) {
System.out.println("📱 [短信服务] 发送短信到: " + to);
System.out.println(" 短信内容: " + content);
return "短信发送成功";
}
@Override
public String getServiceType() {
return "短信";
}
}
3 服务配置文件
创建文件 src/main/resources/META-INF/services/com.example.service.MessageService如下:
# 每一行定义一个服务实现类
com.example.service.impl.EmailServiceImpl
com.example.service.impl.SmsServiceImpl
4 测试类
package com.example;
import com.example.service.MessageService;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
public class Main {
public static void main(String[] args) {
// 1. 基本使用
System.out.println("=== 1. 基本使用 - 获取全部服务 ===");
getAllServices().forEach(s -> {
System.out.println("服务类型: " + s.getServiceType());
s.sendMessage("user@example.com", "Hello!");
System.out.println();
});
System.out.println("=== 2. 使用 Stream API ===");
List<MessageService> services = loadServices();
services.stream()
.filter(s -> s.getServiceType().equals("短信"))
.findFirst()
.ifPresent(s -> s.sendMessage("13800138000", "Stream API 过滤测试"));
System.out.println("\n=== 3. 按类型查找服务 ===");
getServiceByType("邮件").ifPresent(s ->
s.sendMessage("test@example.com", "类型查找测试")
);
System.out.println("\n=== 4. 不存在的服务类型 ===");
getServiceByType("微信").ifPresentOrElse(
s -> s.sendMessage("", ""),
() -> System.out.println("未找到微信服务")
);
System.out.println("\n=== 5. 自定义加载器 ===");
ServiceLoader<MessageService> loader = ServiceLoader.load(MessageService.class);
// 可以通过配置来控制是否懒加载
ServiceLoader<MessageService> reloadedLoader = loader.reload();
reloadedLoader.forEach(s -> {
System.out.println("重新加载服务: " + s.getServiceType());
});
}
/**
* 获取所有服务实现
*/
public static List<MessageService> getAllServices() {
ServiceLoader<MessageService> loader = ServiceLoader.load(MessageService.class);
List<MessageService> services = new ArrayList<>();
for (MessageService service : loader) {
services.add(service);
}
return services;
}
/**
* 使用 Stream API 加载服务
*/
public static List<MessageService> loadServices() {
ServiceLoader<MessageService> loader = ServiceLoader.load(MessageService.class);
return StreamSupport.stream(loader.spliterator(), false)
.collect(Collectors.toList());
}
/**
* 按类型查找服务
*/
public static Optional<MessageService> getServiceByType(String type) {
ServiceLoader<MessageService> loader = ServiceLoader.load(MessageService.class);
return StreamSupport.stream(loader.spliterator(), false)
.filter(s -> s.getServiceType().equals(type))
.findFirst();
}
/**
* 扩展:缓存加载的服务
*/
private static class ServiceCache {
private static List<MessageService> cachedServices;
public static synchronized List<MessageService> getServices() {
if (cachedServices == null) {
cachedServices = getAllServices();
}
return cachedServices;
}
public static void clear() {
cachedServices = null;
}
}
}
增强版:带优先级和配置的服务
package com.example.advanced;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 服务优先级注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ServicePriority {
int value() default 100;
}
增强版服务实例:
package com.example.advanced.impl;
import com.example.advanced.ServicePriority;
import com.example.service.MessageService;
@ServicePriority(10)
public class WeiboServiceImpl implements MessageService {
@Override
public String sendMessage(String to, String content) {
return "微博消息: " + content;
}
@Override
public String getServiceType() {
return "微博";
}
}
高级服务加载工具:
package com.example.advanced;
import com.example.service.MessageService;
import com.example.advanced.ServicePriority;
import java.util.*;
import java.util.stream.Collectors;
public class AdvancedServiceLoader {
private static final Map<String, MessageService> serviceCache = new HashMap<>();
private static final Map<Class<?>, List<?>> genericCache = new ConcurrentHashMap<>();
/**
* 带缓存的服务加载
*/
public static List<MessageService> loadServicesWithCache() {
ServiceLoader<MessageService> loader = ServiceLoader.load(MessageService.class);
List<MessageService> services = new ArrayList<>();
for (MessageService service : loader) {
if (!serviceCache.containsKey(service.getClass().getName())) {
serviceCache.put(service.getClass().getName(), service);
services.add(service);
} else {
services.add(serviceCache.get(service.getClass().getName()));
}
}
return services;
}
/**
* 按优先级排序的服务加载
*/
public static List<MessageService> loadServicesByPriority() {
ServiceLoader<MessageService> loader = ServiceLoader.load(MessageService.class);
return StreamSupport.stream(loader.spliterator(), false)
.sorted(Comparator.comparingInt(
s -> getPriority(s.getClass())
))
.collect(Collectors.toList());
}
/**
* 获取服务优先级
*/
private static int getPriority(Class<?> clazz) {
ServicePriority annotation = clazz.getAnnotation(ServicePriority.class);
return annotation != null ? annotation.value() : 100;
}
/**
* 通用服务加载器
*/
public static <T> List<T> loadAll(Class<T> serviceType) {
@SuppressWarnings("unchecked")
List<T> services = (List<T>) genericCache.computeIfAbsent(
serviceType,
k -> {
ServiceLoader<T> loader = ServiceLoader.load(serviceType);
return StreamSupport.stream(loader.spliterator(), false)
.collect(Collectors.toList());
}
);
return services;
}
}
运行结果示例
=== 1. 基本使用 - 获取全部服务 ===
服务类型: 邮件
📧 [邮件服务] 发送邮件到: user@example.com Hello!
邮件发送成功
服务类型: 短信
📱 [短信服务] 发送短信到: user@example.com Hello!
短信发送成功
=== 2. 使用 Stream API ===
📱 [短信服务] 发送短信到: 13800138000 Stream API 过滤测试
短信发送成功
=== 3. 按类型查找服务 ===
📧 [邮件服务] 发送邮件到: test@example.com 类型查找测试
邮件发送成功
=== 4. 不存在的服务类型 ===
未找到微信服务
=== 5. 自定义加载器 ===
重新加载服务: 邮件
重新加载服务: 短信
使用 Maven 构建
<!-- pom.xml -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>service-loader-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
重要说明
1 ServiceLoader 特性
- 懒加载:服务实现只有在首次使用时才会被实例化
- 自动发现:通过
META-INF/services目录自动发现服务实现 - 解耦:服务接口与实现完全解耦,便于扩展
2 使用场景
- 插件系统开发
- 数据库驱动加载
- 日志框架扩展
- 支付渠道集成
- 消息推送服务
这个案例展示了 ServiceLoader 的核心用法和高级特性,非常适合理解和应用 Java 的服务发现机制。