はじめに
Springでとりあえず簡単なREST APIを作ってサーバを起動したところ↓のエラーに遭遇。
書籍を基に学習をはじめた初学者は、はまるかもと思い備忘録。
error.log
***************************
APPLICATION FAILED TO START
***************************
Description:
Field dao in com.kyosoba.service.KyosobaInfoService required a bean of type 'com.kyosoba.dao.JdbcKyosobaDao' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.kyosoba.dao.JdbcKyosobaDao' in your configuration.
@Component
とか@Autowired
のアノテーションはつけてるしなんでだろう。。
問題のソースコード
以下のコードの何が原因でしょう?(細かいロジックは無視してください)
Controller.java
/**
* Controllerクラス
*/
@RestController
public class KyosobaInfoController {
@Autowired
KyosobaInfoService kyosobaInfoService;
/**
* URIにアクセスされたらデータを返却
*/
@GetMapping("/kyosoba-info-detail")
public KyosobaInfoResource kyoso(String id) {
// サービスクラスを使って検索
KyosobaInfoResource kyosobaInfo = new KyosobaInfoService().findById(0);
return kyosobaInfo;
}
Service.java
/**
* Serviceクラス
*/
@Service
public class KyosobaInfoService {
@Autowired
JdbcKyosobaDao dao;
/**
* 検索ロジック
*/
public KyosobaInfoResource findById(int kyosobaId) {
// DAOクラスを使ってDBアクセス
int i = dao.find();
/* 他処理省略 */
return kyosobaInfoResource;
}
Dao.java
/**
* DAOクラス
*/
@Component
public class JdbcKyosobaDao {
@Autowired
JdbcTemplate jdbcTemplate;
/**
* テーブルアクセス
*/
public int find() {
String sql = "select max(id) from kyosoba";
return jdbcTemplate.queryForObject(sql, Integer.class);
}
}
答え
ControllerクラスでServiceクラスをnewしているnew KyosobaInfoService().findById(0)
が原因でした。newしているとDIが効かなくなるらしいです。
修正後
Controller.java
/**
* Controllerクラス
*/
@RestController
public class KyosobaInfoController {
@Autowired
KyosobaInfoService kyosobaInfoService;
/**
* URIにアクセスされたらデータを返却
*/
@GetMapping("/kyosoba-info-detail")
public KyosobaInfoResource kyoso(String id) {
// サービスクラスを使って検索
KyosobaInfoResource kyosobaInfo = kyosobaInfoService.findById(0); //*** 修正 ***//
return kyosobaInfo;
}
さいごに
書籍を参考にアレンジしながらいろいろごちゃまぜになってしまったのが原因ですね。
参考