#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