스프링 부트 @Autowired with Kotlin in @Service는 항상 null입니다.
현재 Kotlin에서 Java Spring Boot Application을 다시 작성하려고 합니다.나는 내 모든 수업에서 다음과 같이 주석을 다는 문제에 직면했다.@Service종속성 주입이 올바르게 작동하지 않습니다(모든 인스턴스는null)의 예를 다음에 나타냅니다.
@Service
@Transactional
open class UserServiceController @Autowired constructor(val dsl: DSLContext, val teamService: TeamService) {
//dsl and teamService are null in all methods
}
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;
}
컴포넌트에 주석을 달면@Component코틀린에서는 모든 것이 정상적으로 동작합니다.
@Component
open class UserServiceController @Autowired constructor(val dsl: DSLContext, val teamService: TeamService) {
//dsl and teamService are injected properly
}
구글은 Kotlin과 Kotlin을 위해 많은 다른 접근 방식을 제공했습니다.@Autowired내가 시도했지만 모두 같은 결과가 되었다.NullPointerExceptionKotlin과 Java의 차이와 수정 방법을 알고 싶습니다.
방금 똑같은 문제에 부딪혔는데 주입은 잘 되었지만 @Transactional 주석을 추가한 후에는 모든 자동 입력 필드가 null이 됩니다.
내 코드:
@Service
@Transactional
open class MyDAO(val jdbcTemplate: JdbcTemplate) {
fun update(sql: String): Int {
return jdbcTemplate.update(sql)
}
}
여기서의 문제는 메서드가 기본적으로 Kotlin에서 최종적이기 때문에 Spring은 클래스의 프록시를 만들 수 없다는 것입니다.
o.s.aop.framework.CglibAopProxy: Unable to proxy method [public final int org.mycompany.MyDAO.update(...
이 방법을 "열기"하면 문제가 해결됩니다.
고정 코드:
@Service
@Transactional
open class MyDAO(val jdbcTemplate: JdbcTemplate) {
open fun update(sql: String): Int {
return jdbcTemplate.update(sql)
}
}
Kotlin에서 작업하는 경우에도 동일한 문제가 발생했지만 null 인스턴스는 JpaRepository였습니다.를 추가했을 때@Transactional서비스 내 메서드에 대한 주석, 다음과 같은 메시지를 받았습니다.Methods annotated with '@Transactional' must be overridable그래서 나는 수업과 방법 둘 다로 표시했다.open쉽죠?글쎄, 꼭 그렇진 않아.
이것은 컴파일되지만 실행 시 필요한 저장소는 null로 취득되었습니다.저는 두 가지 방법으로 문제를 해결할 수 있었습니다.
- 클래스 및 모든 메서드를 다음과 같이 표시합니다.
open:
open class FooService(private val barRepository: BarRepository) {
open fun aMethod(): Bar {
...
}
@Transactional
open fun aTransactionalMethod(): Bar {
...
}
}
이것은 동작하지만 클래스 내의 모든 메서드에 마크가 붙어 있습니다.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 {
...
}
}
이렇게 하면 모든 메서드를 덮어쓸 수 있으므로 주석을 계속 사용할 수 있습니다.open온통.
도움이 되길 바랍니다 =)
어떤 스프링 부트 버전을 사용하고 있습니까?1.4 Spring Boot은 Spring Framework 4.3을 기반으로 하기 때문에 그 이후로 컨스트럭터 주입을 사용하지 않고 사용할 수 있습니다.@Autowired주석을 달아야 합니다.그거 먹어봤어?
다음과 같이 생겼고, 나에게도 효과가 있습니다.
@Service
class UserServiceController(val dsl: DSLContext, val teamService: TeamService) {
// your class members
}
언급URL : https://stackoverflow.com/questions/41298289/spring-boot-autowired-with-kotlin-in-service-is-always-null
'programing' 카테고리의 다른 글
| 지시사항의 물음표 (0) | 2023.03.23 |
|---|---|
| WooCommerce에서 바리에이션 선택 시 제품 페이지 가격 업데이트 (0) | 2023.03.23 |
| Oracle에서 두 열을 하나의 열로 비교하는 방법 (0) | 2023.03.23 |
| Spring Boot Data JPA with H2 and data.sql - 테이블을 찾을 수 없음 (0) | 2023.03.23 |
| WooCommerce 커스텀 필드 - 다중 선택 (0) | 2023.03.23 |