多模块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.
问题根源
- 模块依赖方向倒置:当前me-domain模块依赖me-api,违背了六边形架构"外层依赖内层"的规则,导致api模块无法加载domain中的Bean。
- 组件扫描规则限制:自定义的
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
相关产品推荐
相关产品推荐

