Skip to content

IoC 容器

Behemiron Engine 提供了一套类似 SpringBoot 的轻量级 IoC(控制反转)AOP(面向切面编程) 框架。

概念导图

Bean 注册

使用注解注册

使用 @Component 或其派生注解标记类:

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

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

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

// 业务服务层
@Service
class UserService

// 数据访问层
@Repository
class UserRepository

注解选择

@Component@Service@Repository 功能相同,只是语义不同。

使用配置类注册

对于需要复杂初始化的 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

AOP 切面编程

Behemiron 的 AOP 基于注解切点,而非表达式切点。

定义标记注解

首先定义用于标记方法的注解:

kotlin
// 定义标记注解
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class Logged

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class Timed

定义切面

kotlin
@Aspect(order = 1)  // order 控制切面执行顺序
class LoggingAspect {

    // 拦截所有标记了 @Logged 的方法
    @Before(Logged::class)
    fun logBefore(joinPoint: JoinPoint) {
        println("调用方法: ${joinPoint.method.name}")
        println("参数: ${joinPoint.args.contentToString()}")
    }

    @After(Logged::class)
    fun logAfter(joinPoint: JoinPoint) {
        println("方法执行完成: ${joinPoint.method.name}")
    }
}

使用标记注解

kotlin
@Service
class UserService {

    @Logged  // 这个方法会被 LoggingAspect 拦截
    fun createUser(name: String): User {
        return User(name)
    }
}

通知类型

@Before - 前置通知

kotlin
@Aspect
class AuthAspect {

    @Before(RequireAdmin::class)
    fun checkAdmin(joinPoint: JoinPoint) {
        if (!currentUser.isAdmin) {
            throw PermissionDeniedException()
        }
    }
}

@After - 后置通知

无论方法是否抛出异常都会执行:

kotlin
@Aspect
class ResourceAspect {

    @After(AutoClose::class)
    fun cleanup(joinPoint: JoinPoint) {
        // 清理资源
    }
}

@AfterReturning - 返回后通知

kotlin
@Aspect
class AuditAspect {

    @AfterReturning(Audited::class, returning = "result")
    fun audit(joinPoint: JoinPoint, result: Any?) {
        println("方法返回: $result")
    }
}

@AfterThrowing - 异常后通知

kotlin
@Aspect
class ErrorAspect {

    @AfterThrowing(Monitored::class, throwing = "ex")
    fun handleError(joinPoint: JoinPoint, ex: Throwable) {
        logger.error("方法异常: ${ex.message}")
    }
}

@Around - 环绕通知

完全控制方法执行:

kotlin
@Aspect
class PerformanceAspect {

    @Around(Timed::class)
    fun measureTime(pjp: ProceedingJoinPoint): Any? {
        val start = System.currentTimeMillis()
        try {
            return pjp.proceed()  // 执行原方法
        } finally {
            val duration = System.currentTimeMillis() - start
            println("耗时: ${duration}ms")
        }
    }
}

JoinPoint API

kotlin
interface JoinPoint {
    val target: Any              // 原始对象
    val proxy: Any               // 代理对象
    val method: Method           // 当前方法
    val args: Array<Any?>        // 方法参数
    val signature: String        // 方法签名
    val targetClass: Class<*>    // 目标类

    fun <T : Annotation> getAnnotation(annotationClass: Class<T>): T?
    fun hasAnnotation(annotationClass: Class<out Annotation>): Boolean
}

interface ProceedingJoinPoint : JoinPoint {
    fun proceed(): Any?                    // 执行原方法
    fun proceed(args: Array<Any?>): Any?   // 使用新参数执行
}

注解参考

Bean 定义

注解属性说明
@Componentvalue, singleton通用组件
@Servicevalue业务服务
@Repositoryvalue数据访问
@IoCConfigurationvalue配置类
@Beanvalue, singletonBean 工厂方法

依赖注入

注解属性说明
@Autowiredvalue, required自动注入
@Qualifiervalue指定 Bean 名称

生命周期

注解说明
@PostConstruct初始化后回调
@PreDestroy销毁前回调
@Lazy延迟加载
@Order初始化顺序

AOP

注解参数说明
@Aspectorder定义切面
@Beforevararg KClass<Annotation>前置通知
@Aftervararg KClass<Annotation>后置通知
@AfterReturningvalue, returning返回后通知
@AfterThrowingvalue, throwing异常后通知
@Aroundvararg KClass<Annotation>环绕通知