首页 > 解决方案 > Spring @Transactional 防止 @Service 中的 @Autowired

问题描述

我有一个服务有一堆@Autowired服务。当我将其中一种方法更改为时@Transactional,它阻止了所有的,@Autowired因为它们都是空的。

例子:

@Service
open class UserService {
    @Autowired
    private val userRepository : UserRepository? = null

    @Autowired
    private val emailService : EmailService? = null

    @Transactional
    @Throws(EmailConflictException::class)
    open fun insert(newUser: User, context : RequestContext) {
        if(!isEmailAvailable(newUser.email)) throw EmailConflictException()
        val user = userRepository!!.insert(newUser, context.org.id)
        emailService!!.send(userEmailFactory!!.getInviteEmail(user))
    }
}

在调用 insert 时,emailService 和 userRepository 在运行时都为空。如果我@Transactional从 insert 方法中删除了,那么 emailService 和 userRepository 都是在运行时定义的。

为什么会这样?我如何解决它

标签: javaspringkotlin

解决方案


此问题通常是由于plugin.spring项目中没有插件引起的。这是因为final默认情况下 Kotlin 类和成员与 Spring AOP 冲突(例如代理 DB 事务)。

plugin.spring是 Spring 注释的包装器,kotlin-allopen包括@Transactional.

尝试添加plugin.spring到您的项目中。例如; 工作配置如下所示。

plugins {
    id("org.springframework.boot") version "2.4.2"
    id("io.spring.dependency-management") version "1.0.11.RELEASE"
    kotlin("jvm") version "1.4.21"
    kotlin("plugin.spring") version "1.4.21"
}

这是文档 - https://kotlinlang.org/docs/all-open-plugin.html#gradle

注意:问题表明类和功能是开放的。理论上应该足够了。但是由于 OP 没有显示完整的项目设置以及如何调用此代码。不确定为什么该open函数没有得到正确初始化的 bean。


推荐阅读