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)
  • 都是为了简化“组件注册”的过程

不同点

  1. 处理时机不同
    • AutoService:编译期处理(Annotation Processing)
    • Spring:运行时处理(反射 + 配置扫描)
  2. 应用范围不同
    • AutoService:专注于 Java SPI,用于插件化、驱动、编译器工具
    • Spring:通用业务开发框架,管理整个应用的对象生命周期
  3. 依赖模型不同
    • AutoService:基于 JDK 原生 ServiceLoader
    • Spring:基于 IoC 容器和 Bean 定义

优劣对比

场景 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