Kotlin

#java #spring #spring-boot #kotlin

#java #весна #пружинный ботинок #kotlin

Вопрос:

У меня есть интерфейс в Kotlin, который является картографом MyBatis:

 @Mapper
interface EquipmentSupportMapper {
    // @Autowired lateinit var metaMapper: MetaMapper // <- Does not work... How?
    @SelectProvider(type = SqlProviderAdapter::class, method = "select")
    fun findMany(selectStatement: SelectStatementProvider?): List<Equipment>
}
 

Затем я добавляю в него реализацию метода:

 fun EquipmentSupportMapper.searchEquipment(
    textSearchValue: String? = null, facilities: Array<Int>? = null,
    manufacturers: Array<Int>? = null, equipmentExample: Equipment? = null
):
        List<Equipment> {
    val builder = SqlBuilder.select(equipmentColumnList)
        .from(EquipmentSupport.EquipmentTable)
        .where()
...
return someList;
 

Теперь, в моем методе searchEquipment , мне нужно @Autowire вызвать spring bean MetaMapper .

Я не могу просто добавить:

@Autowired lateinit var metaMapper: MetaMapper в интерфейсе, потому что он выдает ошибки. Как я могу это сделать?

Комментарии:

1. используйте абстрактный класс вместо интерфейса. Абстрактный класс может иметь автоматически подключаемые свойства

2. No qualifying bean of type 'blah.EquipmentSupportMapper' если я сделаю это абстрактным классом с аннотацией @Mapper

Ответ №1:

Оказывается, я могу это сделать:

 @Mapper
@Qualifier("IESM")
interface InterfaceEquipmentSupportMapper {
    // @Autowired lateinit var metaMapper: MetaMapper // <- Does not work... How?
    @SelectProvider(type = SqlProviderAdapter::class, method = "select")
    fun findMany(selectStatement: SelectStatementProvider?): List<Equipment>
}

@Service
@Qualifier("EquipmentSupportMapper")
class EquipmentSupportMapper(
    @Autowired @Qualifier("IFSM") ifsm: InterfaceEquipmentSupportMapper,
    @Autowired metaMapper: MetaMapper
  ): InterfaceEquipmentSupportMapper by ifsm
 

Хитрость заключается в том, чтобы создать классификатор в интерфейсе, для которого Spring создает реализацию, а затем внедрить его в класс, который реализует тот же интерфейс, делегировав его автоматически созданному компоненту Spring.

Затем Mapper , вместо того, чтобы использовать вызываемый IESM в моем приложении, я просто автоматически подключаюсь к определителю EquipmentSupportMapper и получаю правильный.

Вот пример из теста:

 @SpringBootTest
class EquipmentSupportMapperTest {
    @Autowired
    @Qualifier("EquipmentSupportMapper")
    lateinit var mapper: EquipmentSupportMapper