2016-12-23 7 views
6

Derzeit versuche ich meine Java Spring Boot-Anwendung mit Kotlin umschreiben. Ich habe ein Problem festgestellt, dass in allen meinen Klassen, die mit @Service annotiert sind, die Abhängigkeitsinjektion nicht korrekt funktioniert (alle Instanzen sind null). Hier ein Beispiel:Spring Boot @Autowired mit Kotlin in @Service ist immer Null

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

das gleiche in Java tun funktioniert ohne Probleme:

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

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

Wenn ich die Komponente mit @Component in Kotlin alles mit Anmerkungen versehen funktioniert:

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

Google zur Verfügung gestellt viele verschiedene Ansätze für Kotlin und @Autowired, die ich versuchte, aber alle in der gleichen NullPointerException Ich würde gerne wissen, was der Unterschied zwischen Kotlin und Java ist und wie ich das beheben kann?

+0

Haben Sie versucht, val auf var zu ändern? –

+0

Mögliches Duplikat von [Null Pointer Ausnahme im Frühjahr Proxy-Klasse und Kotlin] (http://stackoverflow.com/questions/37431817/null-pointer-exception-in-spring-proxy-class-and-kotlin) – miensol

+0

Ja, ich schon versuchte beides. – Deutro

Antwort

4

Welche Spring Boot-Version verwenden Sie? Da 1.4 Spring Boot auf Spring Framework 4.3 basiert, sollten Sie in der Lage sein, Konstruktorinjektionen ohne jegliche @Autowired Annotation zu verwenden. Hast du das probiert?

Es würde so aussehen und funktioniert für mich:

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

    // your class members 

} 
+1

Super der Hund :) – davidxxx

+0

Hallo, gibt es eine Möglichkeit, dies zu tun, ohne ein 'No default constructor found' und auch nicht die Eigenschaften Null -fähig? *** (Einige meiner Parameter sind Repositories) *** – jasperagrante

+0

Ich habe mein Problem bereits gelöst. Für diejenigen, die den 'No default constructor' bekommen oder der @Autowired ist bereits gefunden. Stellen Sie sicher, dass Ihr Konstruktor keine Standardwerte hat. – jasperagrante

2

ich in genau gleiche Problem nur gestoßen - Injektion funktionierte gut, aber null @Transactional Anmerkung alle autowired Felder sind nach der Zugabe.

Mein Code:

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

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

} 

Das Problem hierbei ist, dass die Verfahren in Kotlin standardmäßig final sind, so Frühling nicht in der Lage ist, stellvertretend für die Klasse zu erstellen:

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

"Opening" der Methode behebt das Problem:

Festcode:

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

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

} 
+0

Kotlin hat ein Build-Plugin, um diese Klassen zu öffnen: https://kotlinlang.org/docs/reference/compiler-plugins.html –

Verwandte Themen