Skip to content

IoC 容器

类似 SpringBoot 的轻量级 IoC(控制反转)框架,提供 Bean 注册、依赖注入和生命周期管理。

前置知识

需要了解 Kotlin 基础语法 和注解的基本概念。

Quick Start

kotlin
// 1. 定义一个 Bean
@Service
class UserService {
    fun getUser(id: String) = "User($id)"
}

// 2. 注入并使用
@Component
class MyComponent {
    @Autowired
    private lateinit var userService: UserService

    @PostConstruct
    fun init() {
        println(userService.getUser("001"))
    }
}

API Reference

Bean 定义注解

注解参数类型默认值说明
@ComponentvalueString""Bean 名称(空则自动推导)
singletonBooleantrue是否单例
@ServicevalueString""业务服务层,语义等同 @Component
@RepositoryvalueString""数据访问层,语义等同 @Component
@IoCConfigurationvalueString""标记配置类
@BeanvalueString""工厂方法 Bean 名称
singletonBooleantrue是否单例

注解选择

@Component@Service@Repository 功能相同,只是语义不同。选择能体现类职责的注解即可。

依赖注入注解

注解参数类型默认值说明
@AutowiredvalueString""指定 Bean 名称
requiredBooleantrue依赖是否必须存在
@QualifiervalueString按名称限定注入目标

生命周期注解

注解参数类型默认值说明
@PostConstruct依赖注入完成后回调
@PreDestroy应用关闭前回调
@Lazy延迟加载,首次使用时实例化
@OrdervalueInt初始化顺序(数字越小越先)

Bean 注册

使用注解注册

kotlin
// 通用组件(默认单例)
@Component
class MyComponent

// 指定名称
@Component("myName")
class NamedComponent

// 非单例模式
@Component(singleton = false)
class PrototypeComponent

// 业务服务层
@Service
class UserService

// 数据访问层
@Repository
class UserRepository

使用配置类注册

对于需要复杂初始化的 Bean:

kotlin
@IoCConfiguration
class DatabaseConfig {

    @Bean
    fun dataSource(): DataSource {
        return HikariDataSource().apply {
            jdbcUrl = "jdbc:mysql://localhost:3306/mydb"
        }
    }

    // 指定名称和非单例
    @Bean("secondaryDs", singleton = false)
    fun secondaryDataSource(): DataSource {
        return HikariDataSource()
    }
}

依赖注入

字段注入

kotlin
@Service
class OrderService {

    @Autowired
    private lateinit var userService: UserService

    // 可选依赖
    @Autowired(required = false)
    private var cacheService: CacheService? = null
}

按名称注入

当存在多个同类型 Bean 时,使用 @Qualifier

kotlin
@Service
class NotificationService {

    @Autowired
    @Qualifier("emailSender")
    private lateinit var sender: MessageSender
}

生命周期回调

初始化后

kotlin
@Service
class MyService {

    @Autowired
    private lateinit var config: Config

    @PostConstruct
    fun init() {
        // 依赖注入完成后调用
        println("初始化完成,config: $config")
    }
}

销毁前

kotlin
@Service
class ConnectionPool {

    @PreDestroy
    fun cleanup() {
        // 应用关闭前调用
        closeAllConnections()
    }
}

延迟加载与顺序

kotlin
// 延迟加载
@Service
@Lazy
class HeavyService

// 控制初始化顺序(数字越小越先)
@Service
@Order(1)
class FirstService

@Service
@Order(100)
class LastService

完整示例

kotlin
// 配置类:注册需要复杂初始化的 Bean
@IoCConfiguration
class AppConfig {
    @Bean
    fun httpClient(): HttpClient {
        return HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10))
            .build()
    }
}

// 数据访问层
@Repository
class PlayerRepository {
    fun findById(uuid: UUID): PlayerData? = TODO()
}

// 业务服务层
@Service
class PlayerService {
    @Autowired
    private lateinit var repo: PlayerRepository

    @Autowired
    private lateinit var httpClient: HttpClient

    @PostConstruct
    fun init() {
        println("PlayerService 已就绪")
    }

    fun getPlayer(uuid: UUID): PlayerData? = repo.findById(uuid)

    @PreDestroy
    fun shutdown() {
        println("PlayerService 正在关闭")
    }
}

// 使用组件
@Component
@Order(100)
class GameInit {
    @Autowired
    private lateinit var playerService: PlayerService

    @PostConstruct
    fun start() {
        val player = playerService.getPlayer(someUuid)
        println("游戏初始化完成: $player")
    }
}

注意事项

  • @Autowired 字段在构造函数执行时尚未注入,不要在构造函数中访问注入的字段,应使用 @PostConstruct
  • @Component(singleton = false) 的 Bean 每次注入都会创建新实例。
  • 循环依赖会导致启动失败,请合理拆分职责。