Google Auto 项目的一部分,用来简化 Java SPI(Service Provider Interface) 服务注册的注解处理器工具
Google AutoService 简介
作用
- Java SPI 要求你在
META-INF/services/
目录下手动创建一个文件,里面写上接口的实现类的全限定名 Google AutoService
和Lombok实现原理类似用 注解 + 注解处理器 自动生成这个文件,避免手写,减少错误- 适合写 插件系统、编译器插件、自定义注解处理器、日志框架适配等场景
依赖说明
<dependency>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service-annotations</artifactId>
<version>1.1.1</version>
<optional>true</optional>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service</artifactId>
<version>1.1.1</version>
<optional>true</optional>
<scope>compile</scope>
</dependency>
-
auto-service-annotations
只包含
@AutoService
注解,运行时不会用到注解处理器(适合在 library 中暴露) -
auto-service
包含注解 + 注解处理器(Annotation Processor),编译时会自动生成
META-INF/services/...
文件
使用示例
定义接口
public interface UserService {
String userName();
}
定义接口实现,使用AutoService注解
@AutoService(UserService.class)
public class LocalUserService implements UserService {
@Override
public String userName() {
return "local user";
}
}
@AutoService(UserService.class)
public class RemoteUserService implements UserService {
@Override
public String userName() {
return "remote user";
}
}
调用
public class Client {
public static void main(String[] args) {
ServiceLoader<UserService> serviceLoader = ServiceLoader.load(UserService.class);
for (UserService userService : serviceLoader) {
System.out.println(userService.userName());
}
}
}
优点
- 避免手写 SPI 文件,减少路径错误、类名错误
- 统一管理,直接看注解就知道 SPI 注册信息
- 编译期生成文件,不影响运行时性能
和 Spring 的比较
对比维度 | Google AutoService | Spring(例如 Spring Bean 注册) |
---|---|---|
核心用途 | Java SPI 服务注册(编译期自动生成 META-INF/services ) |
Bean 管理与依赖注入(运行时容器管理对象) |
生命周期 | 编译期处理 | 运行时管理 |
使用场景 | 注解处理器、编译插件、JDBC Driver 注册、日志框架实现 | Web 应用、微服务、业务逻辑管理 |
配置方式 | 注解标注 + 编译生成 | 注解/JavaConfig/XML 配置 |
依赖机制 | JDK SPI(ServiceLoader ) |
Spring IoC 容器 |
性能影响 | 无运行时开销 | 容器启动 & Bean 管理有运行时开销 |
灵活性 | 限于 SPI 模式 | 支持各种注入方式、生命周期回调、AOP 等高级功能 |
外部依赖 | 仅依赖 JDK SPI | 依赖 Spring 框架 |
异同总结
相同点
- 都是用注解减少样板代码(boilerplate)
- 都是为了简化“组件注册”的过程
不同点
- 处理时机不同
- AutoService:编译期处理(Annotation Processing)
- Spring:运行时处理(反射 + 配置扫描)
- 应用范围不同
- AutoService:专注于 Java SPI,用于插件化、驱动、编译器工具
- Spring:通用业务开发框架,管理整个应用的对象生命周期
- 依赖模型不同
- AutoService:基于 JDK 原生
ServiceLoader
- Spring:基于 IoC 容器和 Bean 定义
- AutoService:基于 JDK 原生
优劣对比
场景 | AutoService 优势 | Spring 优势 |
---|---|---|
插件化 / 编译期工具 | ✅ 简单、零运行时依赖 | ❌ 配置复杂,没必要为 SPI 引入 Spring |
复杂业务系统 | ❌ 功能有限,只能注册 SPI | ✅ Bean 生命周期管理、AOP、事务等 |
启动速度 | ✅ 编译期生成,无运行时扫描 | ❌ 容器启动慢,运行时扫描消耗时间 |
灵活性 | ❌ 只支持 SPI 模型 | ✅ 支持任意对象、各种注入方式 |
运行环境要求 | ✅ 纯 JDK 就能跑 | ❌ 依赖 Spring 生态 |
flowchart LR subgraph G[Google AutoService - 编译期] A["@AutoService 注解标注"] B["注解处理器 (APT)
读取类信息并生成 SPI 文件"] C["META-INF/services/... 文件"] D["运行时 ServiceLoader.load() 找到实现类"] E["获取 SPI 实现实例"] A --> B --> C --> D --> E end subgraph S["Spring IoC - 运行期"] SA["@Component / @Bean 注解标注"] SB["Spring 容器启动
扫描 classpath 找到 Bean 定义"] SC["实例化 Bean 并注入依赖 (DI)"] SD["调用生命周期回调"] SE["业务代码调用 Bean 方法"] SA --> SB --> SC --> SD --> SE end G --- S