You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多模块Spring Boot+Kotlin项目中RefreshTokenPort Bean找不到问题求助

解决Spring Boot多模块下RefreshTokenPort Bean找不到的问题

错误信息


APPLICATION FAILED TO START


Description:

Parameter 1 of constructor in shop.hyeonme.global.jwt.JwtAdapter required a bean of type 'shop.hyeonme.domain.auth.spi.RefreshTokenPort' that could not be found.

Action:

Consider defining a bean of type 'shop.hyeonme.domain.auth.spi.RefreshTokenPort' in your configuration.

问题根源

  1. 模块依赖方向倒置:当前me-domain模块依赖me-api,违背了六边形架构"外层依赖内层"的规则,导致api模块无法加载domain中的Bean。
  2. 组件扫描规则限制:自定义的ComponentScanConfig仅扫描特定注解的类,而实现类RefreshTokenPersistenceAdapter使用的@Component不在扫描范围内,Spring无法将其注册为Bean。

修复步骤

1. 修正模块依赖关系

修改me-api/build.gradle.kts

添加对me-domain的依赖:

dependencies {
    // 保留原有所有依赖
    implementation(project(":me-domain")) // 新增这一行
}

修改me-domain/build.gradle.kts

移除对me-api的依赖:

dependencies {
    // 删除 implementation(project(":me-api")) 这一行
    // 保留原有其他依赖
}

2. 调整组件扫描规则

任选以下一种方案即可:

方案A:给实现类添加符合扫描规则的注解

将RefreshTokenPersistenceAdapter的@Component替换为扫描列表中的自定义注解,比如@CommandService:

package shop.hyeonme.domain.auth

import shop.hyeonme.common.annotation.CommandService
import shop.hyeonme.domain.auth.mapper.toEntity
import shop.hyeonme.domain.auth.mapper.toModel
import shop.hyeonme.domain.auth.model.RefreshToken
import shop.hyeonme.domain.auth.repository.RefreshTokenRepository
import shop.hyeonme.domain.auth.spi.RefreshTokenPort

@CommandService
class RefreshTokenPersistenceAdapter(
    private val refreshTokenRepository: RefreshTokenRepository
) : RefreshTokenPort {
    override fun saveRefreshToken(refreshToken: RefreshToken): RefreshToken =
        refreshTokenRepository.save(refreshToken.toEntity()).toModel()
}

方案B:修改扫描规则包含@Component

更新ComponentScanConfig,把@Component加入扫描注解列表:

package shop.hyeonme.global.config

import org.springframework.context.annotation.ComponentScan.Filter
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.FilterType
import org.springframework.stereotype.Component
import shop.hyeonme.common.annotation.*

@Configuration
@ComponentScan(
    basePackages = ["shop.hyeonme"],
    includeFilters = [
        Filter(
            type = FilterType.ANNOTATION,
            classes = [
                Component::class, // 新增这一行
                UseCase::class,
                ReadOnlyUseCase::class,
                Service::class,
                QueryService::class,
                CommandService::class
            ]
        )
    ]
)
class ComponentScanConfig

3. 确认启动类扫描范围

确保启动类MeServerApplication的扫描范围覆盖所有模块:

package shop.hyeonme

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication(scanBasePackages = ["shop.hyeonme"])
class MeServerApplication

fun main(args: Array<String>) {
    runApplication<MeServerApplication>(*args)
}

内容的提问来源于stack exchange,提问作者ani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 18:44:52