web-dev-qa-db-ja.com

@ServiceのKotlinを使用したSpringBoot @ Autowiredは常にnullです

現在、Java Spring Boot Application with Kotlinを書き直そうとしています。@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;
    }

Kotlinでコンポーネントに@Componentの注釈を付けると、すべて正常に機能します。

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

GoogleはKotlinと@Autowiredにさまざまなアプローチを提供しましたが、すべて同じNullPointerExceptionになりました。KotlinとJavaの違いは何ですか?どうすればこれを修正できますか?

15
Deutro

まったく同じ問題にぶつかりました-インジェクションはうまく機能しましたが、@ Transactionalアノテーションを追加した後、すべての自動配線フィールドはnullになります。

私のコード:

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

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

} 

ここでの問題は、Kotlinではメソッドがデフォルトでfinalであるため、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)
   }

} 
12
miran

どのSpringBootバージョンを使用していますか? 1.4以降、SpringBootはSpringFramework 4.3に基づいており、それ以降、@Autowiredアノテーションをまったく使用せずにコンストラクターインジェクションを使用できるようになります。あなたはそれを試しましたか?

それはこのように見え、私のために働きます:

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

  // your class members

}
4
David