试图用构造函数调用一个类,但@Autowired var 在 Kotlin/Spring Boot 中抛出空指针异常

我是 Kotlin 和 Spring Boot 的新手。我正在尝试通过 Serviceclass 调用带有初始化构造函数的 SearchService 类,一切都很好,直到需要访问 SearchService 中的 Autowired 环境变量 - 它抛出空指针异常。我假设我必须在 Serviceclass 中自动装配 SearchService,但是我将如何在 performSearch 方法中初始化构造函数和 name/isAlive 变量。

@Service
class Serviceclass {
    @Autowired
    lateinit var env: Environment

    fun performSearch(req: String): String {
        var searchService = SearchService("John",false)
        result = searchService.searchAsync()
            ...
        return result
    }
}

@Repository
class SearchService(name: String = "",isAlive: Boolean = true) {
    private var name: String = name
    private var isAlive: Boolean = isAlive

    @Autowired
    lateinit var env: Environment

    fun searchAsync(): String {
        var endpoint = env.getProperty("endpoint").toString() + name //Error here
        // makes call to get endpoint with Name and isAlive as params
            ...
        return result
    }
}
zhaochunlang1 回答:试图用构造函数调用一个类,但@Autowired var 在 Kotlin/Spring Boot 中抛出空指针异常

您是对的,您也需要自动装配 SearchService。 Spring 只能将依赖项自动装配到它创建的组件中。因为您是自己创建 SearchService,所以 Spring 不知道它存在,也不会自动装配到它。

您的第二个问题是:如果您自动装配 SearchService,您如何初始化它的其他属性,例如 nameisAlive?这是依赖注入的一个常见问题,当构造函数的一些参数是依赖项而其他参数是数据时,就会出现这种问题。

解决方案是使用工厂设计模式。在依赖注入中,它有时也被称为“辅助注入”。创建另一个“工厂”组件,其唯一工作是为您创建 SearchService

@Component
class SearchServiceFactory(private val env: Environment) {
    fun createSearchService(name: String = "",isAlive: Boolean = true) = 
        SearchService(env,name,isAlive)
}

然后您应该从 @Repository 中删除 SearchService 注释,因为它的创建不是由 Spring 直接管理的。

工厂可以在您需要使用它的任何地方自动装配,然后将 Environment 自动装配到其中。当您想要创建 SearchService 时,您可以调用 createSearchService 为附加数据参数提供值。

您的服务类将更改为以下内容:

@Service
class ServiceClass(private val factory: SearchServiceFactory) {
    fun performSearch(req: String): String {
        var searchService = factory.createSearchService("John",false)
        result = searchService.searchAsync()
            ...
        return result
    }
}

请注意,在示例中我使用了构造函数注入而不是 @Autowired。 Spring 会在实例化 Kotlin 类时自动为构造函数参数提供值,就像它是一个自动装配的字段一样。使用构造函数注入而不是字段注入有助于确保在编译时检测到类似您遇到的问题,而不是在运行时导致空指针异常。

本文链接:https://www.f2er.com/3048.html

大家都在问