Проблематично ли аннотировать Базовые и дочерние классы обслуживания?

#spring #kotlin

Вопрос:

Язык программирования не имеет значения для этого вопроса: Котлин и Java в порядке.

В моем проекте у меня есть наследование классов обслуживания. При написании тестов с помощью Mockito выясняется, что @MockBean с дочерними классами это не работает, если я также не аннотирую родительские классы @Service .

Мне хотелось бы знать, проблематично ли весной иметь аннотации к дочерним и родительским классам @Service .

Какие-нибудь проблемы с этим?:

 @Service
abstract class BaseCrudService { ... }

@Transactional
@Service
class PersonService(...) : BaseCrudService { ... }
 

Обратите внимание, что BaseCrudService и то, и PersonService другое снабжено комментариями @Service

Обновить

Отвечая на вопрос М. Дейна, вот полный пример:

Базовый класс:

 abstract class BaseCrudService {
    fun foo() {
        println("BaseCrudService#foo")
    }
}
 

Детский класс:

 @Service
class PersonService : BaseCrudService() {
    fun bar() {
        println("PersonService#bar")
    }
}
 

Контроллер, использующий класс Service/child:

 @Controller
class MyController(val personService: PersonService) {
    fun myMethod() {
        println("MyController#myMethod")
        personService.foo()
        personService.bar()
    }
}
 

Тест:

 @WebMvcTest(MyController::class)
class MyControllerTest {
    @MockBean
    lateinit var personService: PersonService

    @Autowired
    lateinit var myController: MyController

    @Test
    fun testMyMethod() {
        myController.myMethod()
    }
}
 

Without annotating the base class with @Service the test output is:

 MyController#myMethod
BaseCrudService#foo
 

Как вы можете видеть, метод дочернего класса подвергается насмешкам (без вывода), но вызывается метод базового класса (имеет вывод).

С аннотацией @Service abstract class BaseCrudService { ... } вывод будет:

 MyController#myMethod
 

Методы дочернего и родительского классов подвергаются насмешкам.

При аннотировании как родительского, так и дочернего класса с помощью @Service я получаю ожидаемое поведение. Но мне интересно, есть ли какие-либо проблемы с аннотацией обоих классов с помощью @Service для Spring?

Обновление 2

В предыдущем примере проблема BaseCrudService#foo является окончательной. В Kotlin методы являются общедоступными, окончательными по умолчанию, см. Эту статью.

Mockito не выводил никаких предупреждений (возможно, из-за настроек журнала). Он не может имитировать окончательные методы, см. Эту статью. После взлома BaseCrudService#foo open я могу безопасно удалить @Service из BaseCrudService . @Service родительскому классу волшебным образом позволяет Mockito издеваться над конечным методом. Поэтому мне нужно найти способ издеваться над окончательным методом (это не входит в вопрос).

Но независимо от того, что касается насмешки, вопрос остается открытым.

В статье, где должна храниться аннотация Spring @Service? обсуждается другой способ: аннотируется только (абстрактный) родительский класс @Service , но не дочерний класс.

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

1. Описание вашей проблемы не имеет смысла. Почему бы это не сработало, с какой проблемой вы столкнулись?

Ответ №1:

 @Service
abstract class BaseCrudService { ... }
 

Здесь вы объявили свой класс абстрактным. У Spring не будет способа создать экземпляр, как вы проинструктировали его сделать с @Service

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

1. Спасибо! Так что Весна может спокойно игнорировать это? Никаких проблем с производительностью или проблем с инструментами?