首页 > 解决方案 > 注释基类和子服务类是否有问题?

问题描述

对于这个问题,编程语言无关紧要:Kotlin 和 Java 都可以。

在我的项目中,我继承了服务类。事实证明,在使用 Mockito 编写测试时,@MockBean如果我不注释父类,子类将不起作用@Service

我想知道在 Spring 中让子类和父类用@Service.

有什么问题吗?:

@Service
abstract class BaseCrudService { ... }

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

注意BaseCrudServicePersonService都用@Service

更新

回答 M. Deinum 的问题,这里有一个完整的例子:

基类:

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

儿童班:

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

使用服务/子类的控制器:

@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()
    }
}

@Service没有用测试输出注释基类是:

MyController#myMethod
BaseCrudService#foo

如您所见,子类的方法被模拟(无输出),但基类的方法被调用(有输出)。

使用注释@Service abstract class BaseCrudService { ... },输出为:

MyController#myMethod

子类和父类的方法被嘲笑。

通过使用@Service 注释父类和子类,我得到了预期的行为。但我想知道用 @Service for Spring 注释两个类是否有任何问题?

更新 2

在前面的示例中,问题BaseCrudService#foofinal。在 Kotlin 中方法是公开的,默认为 final,请参阅这篇文章

Mockito 没有输出任何警告(可能是因为日志设置)。它无法模拟最终方法,请参阅这篇文章。macking 后BaseCrudService#foo open,我可以安全地@ServiceBaseCrudService. @Service到父类神奇地允许 Mockito 模拟最终方法。所以我需要找到一种模拟最终方法的方法(这不是问题的一部分)。

但不管对 Mockito 来说,问题仍然存在。

文章Spring @Service 注解应该保存在哪里?讨论另一种方式:只有(抽象)父类被注释,@Service但子类没有。

标签: springkotlin

解决方案


@Service
abstract class BaseCrudService { ... }

在这里,您已将您的类声明为抽象类。Spring 将无法按照您的指示创建实例@Service


推荐阅读