この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
SpringBoot楽しいですよね。
クラスを作って@Componentを書いて、@Autowireでメンバーに注入する。なんて楽にかけるんだ!!と思っていたのですが、少しクラス数も多くなってきたのでパッケージを分けてみたら
org.springframework.beans.factory.NoSuchBeanDefinitionException
とエラーが返ってきたので回避方法を調べました。
環境
Spring Tool Suite 3.8.0
失敗したコード
うまくいかなかったコードがこんな感じです。かなり簡略化はしています。
├ com.example/
│ ├ SpringBootPracticeApplication
│ └ BatchProcessing
└ nextPackage/
└ Hoge
package com.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import nextPackage.Hoge;
@SpringBootApplication
@EnableScheduling
public class SpringBootPracticeApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootPracticeApplication.class, args);
}
}
@EnableSchedulingと下の@Scheduledは定期実行するために必要なアノテーションになります。興味のある方はこちらをどうぞ!
package com.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import nextPackage.Hoge;
@Service
public class BatchProcessing {
@Autowired
Hoge hoge;
@Scheduled(fixedDelay = 5000)
public void fixedRate(){
System.out.println(hoge.getHoge());
}
}
ちゃんとimportもしているのになんで?
package nextPackage;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
@Component
public class Hoge {
public String getHoge(){
return "hoge";
}
}
上のコードは単純に5秒おきにgetHogeで返される文字列を表示するだけのものです。
回避方法
答えとしては非常に簡単で
@Service
@ComponentScan("nextPackage")
public class BatchProcessing {
@Autowired
Hoge hoge;
@Scheduled(fixedDelay = 5000)
public void fixedRate(){
System.out.println(hoge.getHoge());
}
}
パッケージ外はScanしてないから明示的に指定する必要があるようですね。 @ComponentScan("")で指定することによって解決しました。
他にも@Autowiredするクラスを同一パッケージにする方法なんかもあるようです。
最後に
何通りか方法はあるようですが、パッケージ構成を変えてまでやるほどのことでもないので@ComponentScan("")を使うのが現実的ではないかなと思いました。
参考
https://teratail.com/questions/4532