【问题标题】:Autowiring Generic in Spring Boot / Kotlin在 Spring Boot / Kotlin 中自动装配泛型
【发布时间】:2020-01-15 07:39:48
【问题描述】:

目前我有如下课程:

interface Mapper<IN, OUT> {
    fun map(input: IN): OUT
}

@Service
class ContractPhaseMapper: Mapper<Contract, List<ContractPhase>> {
    override fun map(input: Contract): List<ContractPhase> = contract.phases.map { 
        ContractPhase(...)
    }
}

@Service
class ContractPhaseProcessor(private val contractPhaseMapper: Mapper<Contract, List<ContractPhase>>) {
    fun createResponse(contracts: List<Contract>) = SomeResponse(
        contractPhases = contracts.map { contractPhaseMapper.map(it) }.flatten()
    )
}

不幸的是,这导致 Spring 退出并显示消息:

Parameter # of constructor in my.package.ContractPhaseProcessor required a bean of type 'my.package.mapper.Mapper' that could not be found.

如果我尝试像 Mapper&lt;Contract, Customer&gt; 这样的映射器,它会正常工作。

我也尝试使用@Qualifier 使其明确使用此服务,但它仍然不起作用。

有人知道这个问题的简单解决方案吗?

【问题讨论】:

    标签: spring spring-boot generics kotlin


    【解决方案1】:

    我无法弄清楚为什么您的方法不起作用 - 但我已经重现了您的问题并可以建议您解决方法:如果您使用 @Configuration 注释类而不是 @Service 注释来配置 Spring bean ,一切正常:

    class ContractPhaseMapper: Mapper<Contract, List<ContractPhase>> {
        override fun map(input: Contract): List<ContractPhase> = ...
    }
    
    class ContractPhaseProcessor(private val contractPhaseMapper: Mapper<Contract, List<ContractPhase>>) {
        fun createResponse(contracts: List<Contract>) : String = ...
    }
    
    @Configuration
    open class MyConfiguration {
        @Bean
        open fun mapper() : Mapper<Contract, List<ContractPhase>> = ContractPhaseMapper()
    
        @Bean
        open fun processor(mapper: Mapper<Contract, List<ContractPhase>>) : ContractPhaseProcessor = ContractPhaseProcessor(mapper)
    }
    
    // Main function, that wires up the application context deriving bean definitions
    //  from the given class MyConfiguration, annotated with @Configuration
    fun main() {
       AnnotationConfigApplicationContext(MyConfiguration::class.java).use { context ->
            val component = context.getBean(ContractPhaseProcessor::class.java)
            println(component)
            println(component.createResponse(listOf()))
        }
    }
    

    我希望这可以帮助您解决问题!

    【讨论】:

    • 这不是我真正喜欢的选择,但现在似乎可以解决问题。
    猜你喜欢
    • 2014-05-16
    • 1970-01-01
    • 2022-01-24
    • 2017-09-07
    • 1970-01-01
    • 2019-07-14
    • 2019-05-03
    • 2016-10-03
    • 1970-01-01
    相关资源
    最近更新 更多