Deu*_*tro 15 java spring spring-mvc kotlin spring-boot
目前我尝试使用Kotlin重写我的Java Spring Boot应用程序.我遇到了一个问题,在我的所有使用@Service依赖注入注释的类中都没有正常工作(所有实例都是null).这是一个例子:
@Service
@Transactional
open class UserServiceController @Autowired constructor(val dsl: DSLContext, val teamService: TeamService) {
//dsl and teamService are null in all methods
}
Run Code Online (Sandbox Code Playgroud)
在Java中做同样的工作没有任何问题:
@Service
@Transactional
public class UserServiceController
{
private DSLContext dsl;
private TeamService teamService;
@Autowired
public UserServiceController(DSLContext dsl,
TeamService teamService)
{
this.dsl = dsl;
this.teamService = teamService;
}
Run Code Online (Sandbox Code Playgroud)
如果我用@ComponentKotlin 注释组件一切正常:
@Component
open class UserServiceController @Autowired constructor(val dsl: DSLContext, val teamService: TeamService) {
//dsl and teamService are injected properly
}
Run Code Online (Sandbox Code Playgroud)
谷歌为Kotlin提供了许多不同的方法,@Autowired但我尝试了所有方法,但NullPointerException
我想知道Kotlin和Java之间的区别是什么以及如何解决这个问题?
mir*_*ran 13
我只是碰到了完全相同的问题 - 注入效果很好,但在添加@Transactional注释后,所有自动连接的字段都为空.
我的代码:
@Service
@Transactional
open class MyDAO(val jdbcTemplate: JdbcTemplate) {
fun update(sql: String): Int {
return jdbcTemplate.update(sql)
}
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是默认情况下Kotlin中的方法是final的,所以Spring无法为类创建代理:
o.s.aop.framework.CglibAopProxy: Unable to proxy method [public final int org.mycompany.MyDAO.update(...
Run Code Online (Sandbox Code Playgroud)
"打开"方法修复了问题:
固定代码:
@Service
@Transactional
open class MyDAO(val jdbcTemplate: JdbcTemplate) {
open fun update(sql: String): Int {
return jdbcTemplate.update(sql)
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
我在使用 Kotlin 时遇到了同样的问题,但 null 实例是 JpaRepository。当我将@Transactional注释添加到服务内的方法时,我收到一条消息,说Methods annotated with '@Transactional' must be overridable所以我继续将类和方法都标记为open. 很容易,对吧?嗯,不完全是。
尽管可以编译,但我在执行时将所需的存储库设置为空。我能够通过两种方式解决这个问题:
open:open class FooService(private val barRepository: BarRepository) {
open fun aMethod(): Bar {
...
}
@Transactional
open fun aTransactionalMethod(): Bar {
...
}
}
Run Code Online (Sandbox Code Playgroud)
这可行,但是将类中的所有方法标记为open可能看起来有点奇怪,所以我尝试了其他方法。
interface IFooService {
fun aMethod(): Bar
fun aTransactionalMethod(): Bar
}
open class FooService(private val barRepository: BarRepository) : IFooService {
override fun aMethod(): Bar {
...
}
@Transactional
override fun aTransactionalMethod(): Bar {
...
}
}
Run Code Online (Sandbox Code Playgroud)
这样您仍然可以使用注释,因为所有方法都将是可重写的,并且您不需要open在任何地方使用。
希望这有帮助 =)
您使用哪个 Spring Boot 版本?由于 1.4 Spring Boot 基于 Spring Framework 4.3,从那时起您应该能够使用构造函数注入而无需任何@Autowired注释。你尝试过吗?
它看起来像这样并且对我有用:
@Service
class UserServiceController(val dsl: DSLContext, val teamService: TeamService) {
// your class members
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5129 次 |
| 最近记录: |