現在、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の違いは何ですか?どうすればこれを修正できますか?
まったく同じ問題にぶつかりました-インジェクションはうまく機能しましたが、@ 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)
}
}
どのSpringBootバージョンを使用していますか? 1.4以降、SpringBootはSpringFramework 4.3に基づいており、それ以降、@Autowired
アノテーションをまったく使用せずにコンストラクターインジェクションを使用できるようになります。あなたはそれを試しましたか?
それはこのように見え、私のために働きます:
@Service
class UserServiceController(val dsl: DSLContext, val teamService: TeamService) {
// your class members
}