タイトル: Field ... required a bean of type ... hat could not be found.
SEOタイトル: 【Springエラー】Field ... required a bean of type ... hat could
| この記事の要点 |
|---|
|
エラーの状況
***************************
APPLICATION FAILED TO START
***************************
Description:
Field userRepository in com.example.UserService required a bean of type
'com.example.UserRepository' that could not be found.
Action:
Consider defining a bean of type 'com.example.UserRepository' in your configuration.
Spring が UserService の userRepository フィールドに注入すべき Bean を見つけられなかった、というエラー。アプリ起動自体が失敗します。
主な原因と対処
原因 1: Bean としてアノテーションされていない
// ダメな例
public class UserRepository { // ← @Repository などなし
public User findById(Long id) { ... }
}
@Service
public class UserService {
@Autowired
private UserRepository userRepository; // ← Bean がない → 注入失敗
}
// 修正
@Repository
public class UserRepository { ... }
原因 2: @ComponentScan の範囲外
// メインクラス
package com.example;
@SpringBootApplication // デフォルトで com.example 以下をスキャン
public class MyApp { ... }
// com.example.service.UserService → OK
// com.example.repository.UserRepository → OK
// com.other.UserRepository → スキャン対象外!
// 修正: スキャン範囲を広げる
@SpringBootApplication(scanBasePackages = {"com.example", "com.other"})
// または
@ComponentScan(basePackages = {"com.example", "com.other"})
原因 3: インタフェースに対応する実装クラスがない
public interface UserRepository {
User findById(Long id);
}
@Service
public class UserService {
private final UserRepository userRepository; // インタフェースで型指定
// ← UserRepository を実装したクラスが Bean になっていない → エラー
}
// 修正案 1: 実装クラスを作って @Component
@Repository
public class UserRepositoryImpl implements UserRepository {
public User findById(Long id) { ... }
}
// 修正案 2: Spring Data JPA なら interface 自動実装
@Repository
public interface UserRepository extends JpaRepository {
// Spring が自動でプロキシ実装を作る
}
原因 4: @Configuration の @Bean メソッドが漏れている
@Configuration
public class AppConfig {
// この Bean が定義されていなければエラー
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
原因 5: @Profile で除外されている
@Service
@Profile("prod") // prod プロファイルのときだけ Bean になる
public class ProductionUserRepository implements UserRepository { ... }
# アクティブプロファイルが dev だと UserRepository の Bean がない
# 修正
# application.properties
spring.profiles.active=prod
# または開発用 Bean も用意
@Service
@Profile("dev")
public class DevUserRepository implements UserRepository { ... }
原因 6: starter / 依存ライブラリ未追加
// 例: spring-data-jpa を入れ忘れて Repository を作っている
// pom.xml に追加
org.springframework.boot
spring-boot-starter-data-jpa
// 例: DB ドライバの依存忘れ
com.h2database
h2
runtime
注入先と注入元の組み合わせ確認
| 注入先 (フィールド型) | 注入元の Bean 名 / 型 | 必要な前提 |
|---|---|---|
UserRepository | 同名 or 実装クラス | @Component / @Repository |
List | Notifier 型の全 Bean | 複数 @Component |
Map | Bean 名をキー | 同上 |
Optional | 0 個 or 1 個許容 | 同上 (空でも OK) |
デバッグ Tips
① 全 Bean をログ出力
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(MyApp.class, args);
String[] names = ctx.getBeanDefinitionNames();
Arrays.sort(names);
for (String name : names) System.out.println(name);
}
}
② actuator/beans エンドポイント
# application.properties
management.endpoints.web.exposure.include=beans
# 確認
$ curl http://localhost:8080/actuator/beans | jq .
③ デバッグログ
logging.level.org.springframework.beans=DEBUG
logging.level.org.springframework.context=DEBUG
同型 Bean が複数あるパターン (BeanNotOfRequiredTypeException / NoUniqueBean)
逆に「Bean がない」ではなく「複数あって絞り込めない」場合は NoUniqueBeanDefinitionException:
// 解決策
@Service
public class UserService {
// @Qualifier で名前指定
public UserService(@Qualifier("primaryNotifier") Notifier notifier) { ... }
// または @Primary で優先指定
}
@Primary
@Service
public class EmailNotifier implements Notifier { ... }