# AutoService **Repository Path**: ym521/autoservice ## Basic Information - **Project Name**: AutoService - **Description**: 自动注入框架 - **Primary Language**: Unknown - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-07 - **Last Updated**: 2026-06-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AutoService - 编译期自动注入框架 最新发布的版本: [![](https://jitpack.io/v/com.gitee.ym521/autoservice.svg)](https://jitpack.io/#com.gitee.ym521/autoservice) 一个轻量级 Android DI(依赖注入)框架,基于注解处理器(APT)在编译期自动生成服务注册与注入代码,零反射、零运行时开销。 1. 框架定位和原理(编译期 APT、零反射) 2. 从 JitPack 安装(Gradle 配置、Java/Kotlin 区别) 3. 5 步上手流程(定义接口 → 标注 @Service → 初始化 → @Inject 注入 → 手动获取) --- ## 功能特性 - **编译期代码生成**:基于 `@Service` 注解,编译时自动生成服务注册表,无运行时反射 - **接口驱动**:自动识别实现类所实现的接口,以接口名称作为服务标识 - **字段注入**:通过 `@Inject` 注解自动注入依赖 - **服务查找**:支持按名称手动获取服务实例 - **线程安全**:初始化过程异步执行,注入时自动等待就绪 - **调试日志**:内置日志开关,方便排查问题 --- ## 软件架构 1. di-annotations → 注解定义层(@Service / @Inject) 2. di-compiler → 注解处理器,编译期生成服务注册代码 3. di-api → 运行时 API,提供 AutoService 入口 ┌─────────────────────────────────────────────────────┐ │ 消费者 App/模块 │ │ @Service @Inject → 注解处理器触发 → 生成注册代码 │ └──────────────────────┬──────────────────────────────┘ │ 依赖 ┌──────────────────────┴──────────────────────────────┐ │ di-compiler (编译期注解处理器) │ │ processors/ + utils/ + constants/ │ │ 扫描注解 → 校验 → 生成 Java 源码文件 │ └──────────────────────┬──────────────────────────────┘ │ 依赖 ┌──────────────────────┴──────────────────────────────┐ │ di-annotations (注解定义层) │ │ @Service @Inject │ └──────────────────────┬──────────────────────────────┘ │ 依赖 ┌──────────────────────┴──────────────────────────────┐ │ di-api (运行时 API) │ │ AutoService 入口 → _DIService → _Injector │ │ 初始化 → Dex扫描 → 注册服务 → 等待注入 │ └─────────────────────────────────────────────────────┘ --- ## @Service 属性说明 | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `name` | String | `""` | 自定义服务名称,为空时自动使用接口简单名 | | `singleton` | boolean | `true` | `true`=单例,`false`=非单例(每次获取创建新实例) | > **注意**:Kotlin `object` 类即使标记为 `@Service(singleton = false)`,也会按单例处理——这是 Kotlin 语言特性决定的,无法创建额外实例。 ## @Inject 属性说明 | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `name` | String | `""` | 自定义服务名称,为空时自动使用字段类型或方法参数类型的简单名 | --- ## 编译期优化说明 AutoService 在编译期做了两件事来消除运行时反射: | 阶段 | 处理器 | 生成产物 | 效果 | |------|--------|---------|------| | @Service | `ServiceProcessor` | `ServiceRegistry_xxx` | 编译期确定服务实现类,避免运行时扫描 | | @Inject | `InjectProcessor` | `InjectRegistry_xxx` + `InjectHelper_*` | 编译期预生成 InjectMeta,`inject()` 时零反射扫描 | 即使依赖的第三方库未使用本框架,运行时也会优雅降级为反射扫描,不影响功能。 --- ## 安装教程 ### 1. 在根 `build.gradle` 中添加 JitPack 仓库 Android Gradle Plugin 为 v7.1.0 以下版本:进入项目根目录,打开 “build.gradle” 文件,在 “allprojects” 中加入如下代码: ```groovy ... allprojects { repositories { maven { url 'https://jitpack.io' } mavenCentral() google() } } ``` 当您的 Android Gradle Plugin 为 v7.1.0 或以上版本:进入项目根目录,打开 “settings.gradle” 文件,在 “dependencyResolutionManagement” 中加入如下代码: ```groovy ... dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { maven { url 'https://jitpack.io' } mavenCentral() google() } } ``` ### 2. 在模块 `build.gradle` 中添加依赖 最新可用的版本: [![](https://jitpack.io/v/com.gitee.ym521/autoservice.svg)](https://jitpack.io/#com.gitee.ym521/autoservice) ```groovy dependencies { ··· // 运行时 API implementation 'com.gitee.ym521.autoservice:di-api:latest version' // 注解处理器(Java 项目用 annotationProcessor,Kotlin 项目用 kapt) annotationProcessor 'com.gitee.ym521.autoservice:di-compiler:latest version' } ``` Kotlin 项目需额外配置: ```groovy plugins { ··· id 'kotlin-kapt' } dependencies { ··· implementation 'com.gitee.ym521.autoservice:di-api:latest version' kapt 'com.gitee.ym521.autoservice:di-compiler:latest version' } ``` --- ## 初始化与使用 ### 1️⃣ 初始化框架 在 `Application.onCreate()` 中初始化,建议放在其他业务初始化之前: ```kotlin class App : Application() { override fun onCreate() { super.onCreate() AutoService.init(this) .debug(true) // 开启调试日志(可选) } } ``` `init()` 会在后台线程异步执行 Dex 扫描和服务注册,不会阻塞主线程。 > **注意**:确保 `AndroidManifest.xml` 中 `application` 的 `android:name` 指向你的 Application 类。 --- ### 2️⃣ 定义服务接口与实现 ```kotlin // 1. 定义接口 interface LoginService { fun smsLogin() fun passwordLogin() } // 2. 用 @Service 标记实现类 @Service // 默认单例,接口名作为服务名 class LoginServiceImpl : LoginService { override fun smsLogin() { /* ... */ } override fun passwordLogin() { /* ... */ } } ``` 也可指定自定义服务名和生命周期: ```kotlin @Service(name = "MyLogin", singleton = false) class MyLoginImpl : LoginService { /* ... */ } ``` --- ### 3️⃣ 注入依赖 字段注入(推荐): ```kotlin class MainActivity : BaseActivity() { @Inject private var loginService: LoginService? = null @Inject(name = "MyLogin") // 指定服务名注入 private var myLoginService: LoginService? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 前提:已调用 AutoService.inject(this) loginService?.smsLogin() } } ``` 需要在基类或 `onCreate` 中触发注入: ```kotlin abstract class BaseActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) AutoService.inject(this) // 自动注入所有 @Inject 字段 } } ``` 方法注入(支持一个参数): ```kotlin class MainActivity : BaseActivity() { @Inject fun setLoginService(loginService: LoginService) { // 方法会在注入时被调用 } } ``` --- ### 4️⃣ 手动获取服务 ```kotlin // 按服务名获取 val loginService = AutoService.getService("LoginService") // 非单例模式下,每次 getService 都会创建新实例 val newInstance = AutoService.getService("MyLogin") ``` --- ### 完整示例 ```kotlin // App.kt — 初始化 class App : Application() { override fun onCreate() { super.onCreate() AutoService.init(this) } } // LoginService.kt — 服务接口 interface LoginService { fun doSomething(): String } // LoginServiceImpl.kt — 服务实现 @Service class LoginServiceImpl : LoginService { override fun doSomething() = "Hello from DI" } // MainActivity.kt — 使用 class MainActivity : BaseActivity() { @Inject private var loginService: LoginService? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Toast.makeText(this, loginService?.doSomething(), Toast.LENGTH_LONG).show() } } ``` --- # 设计亮点 1. 零反射声明:@Service 的服务实例化是 Class.forName + newInstance(标准的 Java SPI 方式),不是"反射扫描"。@Inject 的注入点发现已从编译期预生成,运行时仅执行 field.set() 赋值。 2. 优雅降级:scanAndCache 先查编译期生成的 IInjectHelper,没有则回退到运行时反射扫描,兼容第三方库或未使用本框架的模块。 3. 异步初始化:框架初始化在后台线程执行,inject() 通过 CountDownLatch 等待最多 5 秒,不阻塞主线程启动流程。 4. Kotlin Object 兼容:isKotlinObject() 检测 INSTANCE 静态字段,对 Kotlin object 走 INSTANCE 获取而非 newInstance()。 ```mermaid **graph TB** subgraph "di-annotations(注解定义)" A1["@Service
name / singleton"] A2["@Inject
name"] end subgraph "di-compiler(编译期处理)" B1["ServiceProcessor"] --> B2["ServiceCollector"] B1 --> B3["ClassGenerate"] B3 --> G1["ServiceRegistry_xxx
(IServiceRegistry)"] B4["InjectProcessor"] --> B5["InjectCollector"] B4 --> B3 B3 --> G2["InjectRegistry_xxx
(IServiceRegistry)"] G2 --> G3["InjectHelper_*
(IInjectHelper)"] end subgraph "di-api(运行时)" C1["AutoService
init/inject/getService"] C1 --> C2["_DIService"] C2 --> C3["ClassFind
Dex扫描"] C2 --> C4["_Injector"] C4 --> C5["serviceMap
单例缓存"] C4 --> C6["nonSingletonClassMap
非单例Class"] C4 --> C7["injectCacheMap
注入元缓存"] C4 --> C8["injectHelperMap
编译期Helper"] C4 --> C9["InjectMeta
field.set / method.invoke"] end subgraph "运行时注册" G1 -->|"register()"| C5 G1 -->|"register()"| C6 G2 -->|"register()"| C8 end subgraph "注入时" C7 -->|"命中缓存"| C9 C8 -->|"Helper优先"| C7 C7 -->|"未命中→反射扫描"| C9 end ```