2016-12-23 13 views
6

Obecnie próbuję przepisać moją aplikację Java Spring Boot Application z Kotlinem. Napotkano problem polegający na tym, że we wszystkich moich klasach opatrzonych przypisami @Service zastrzyk zależności nie działa poprawnie (wszystkie wystąpienia to null). Oto przykład:Spring Boot @Aktowijowany z Kotlin w @Service jest zawsze pusty null

@Service 
@Transactional 
open class UserServiceController @Autowired constructor(val dsl: DSLContext, val teamService: TeamService) { 
    //dsl and teamService are null in all methods 
} 

robi to samo w Java działa bez żadnych problemów:

@Service 
@Transactional 
public class UserServiceController 
{ 
    private DSLContext dsl; 
    private TeamService teamService; 

    @Autowired 
    public UserServiceController(DSLContext dsl, 
          TeamService teamService) 
    { 
     this.dsl = dsl; 
     this.teamService = teamService; 
    } 

Gdybym opisywanie komponent z @Component w Kotlin wszystko działa poprawnie:

@Component 
open class UserServiceController @Autowired constructor(val dsl: DSLContext, val teamService: TeamService) { 
    //dsl and teamService are injected properly 
} 

Google dostarczyłem wiele różnych podejść dla Kotlin i @Autowired, których próbowałem, ale wszystkie skutkowały tym samym NullPointerException Chciałbym wiedzieć, jaka jest różnica między Kotlin a Javą i jak mogę to naprawić?

+0

Czy próbowałeś zmienić val na var? –

+0

Możliwy duplikat [Wyjątek zerowego wskaźnika w klasie Proxy wiosny i Kotlin] (http://stackoverflow.com/questions/37431817/null-pointer-exception-in-spring-proxy-class-and-kotlin) – miensol

+0

Tak, już jestem wypróbowałem oba. – Deutro

Odpowiedz

4

Którą wersję Spring Boot używasz? Ponieważ 1.4 Spring Boot jest oparty na Spring Framework 4.3 i od tego czasu powinieneś być w stanie używać iniekcji konstruktora bez żadnej adnotacji @Autowired. Czy próbowałeś tego?

To będzie wyglądać tak i pracuje dla mnie:

@Service 
class UserServiceController(val dsl: DSLContext, val teamService: TeamService) { 

    // your class members 

} 
+1

Super the dog :) – davidxxx

+0

Witam, czy istnieje sposób, aby to zrobić bez uzyskania 'Brak domyślnego konstruktora found', a także nie powodując, że właściwości są zerowe -zdolny? *** (FYI Niektóre z moich parametrów są repozytoriami) *** – jasperagrante

+0

Już rozwiązałem mój problem. Dla tych, którzy otrzymują 'Brak domyślnego konstruktora' lub @Autowired jest już znaleziony. Upewnij się, że twój konstruktor nie ma wartości domyślnych. – jasperagrante

2

Właśnie natknąłem się na dokładnie tej samej kwestii - wtrysk działa dobrze, ale po dodaniu @Transactional adnotacji wszystkie autowired pola są puste.

Mój kod:

@Service 
@Transactional 
open class MyDAO(val jdbcTemplate: JdbcTemplate) { 

    fun update(sql: String): Int { 
     return jdbcTemplate.update(sql) 
    } 

} 

Problem polega na tym, że metody są ostateczne domyślnie w Kotlin, więc wiosna jest w stanie stworzyć serwer proxy dla klasy:

o.s.aop.framework.CglibAopProxy: Unable to proxy method [public final int org.mycompany.MyDAO.update(... 

"otwarcia" The metoda rozwiązuje problem:

kod Poprawiono:

@Service 
@Transactional 
open class MyDAO(val jdbcTemplate: JdbcTemplate) { 

    open fun update(sql: String): Int { 
     return jdbcTemplate.update(sql) 
    } 

} 
+0

Kotlin ma wtyczkę do budowania, aby otworzyć te klasy: https://kotlinlang.org/docs/reference/compiler-plugins.html –