20.

Spring Bean の中身を確認する 7 つの方法(Actuator / Context / DevTools / デバッガ)

編集
この記事の要点
  • 最速: ApplicationContext#getBean()getBeansOfType() でランタイム取得
  • 本番でも安全: Spring Boot Actuator の /actuator/beans エンドポイント
  • 起動時ログ: @PostConstruct でフィールドをログ出力
  • JSON 化: Jackson ObjectMapper でフィールドをまとめてダンプ
  • IDE デバッガ: ブレークポイントで Bean 全体をインスペクト

方法1: ApplicationContext から取得

もっとも単純な方法。ApplicationContext を注入して任意の Bean を取り出す:

@RestController
public class BeanDumpController {
    @Autowired
    private ApplicationContext ctx;

    @GetMapping("/debug/beans")
    public Map all() {
        // 登録されている全 Bean 名
        String[] names = ctx.getBeanDefinitionNames();
        Arrays.sort(names);

        Map result = new LinkedHashMap<>();
        for (String name : names) {
            Object bean = ctx.getBean(name);
            result.put(name, bean.getClass().getName());
        }
        return result;
    }

    @GetMapping("/debug/bean/{name}")
    public Object byName(@PathVariable String name) {
        Object bean = ctx.getBean(name);
        return bean.toString();   // Lombok @ToString 推奨
    }
}

方法2: 型で取得 (getBeansOfType)

// 特定インターフェースの実装を全部取得
Map repos = ctx.getBeansOfType(UserRepository.class);
repos.forEach((name, bean) -> {
    System.out.println(name + " = " + bean);
});

// 親クラスからの継承も含めて
String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
    ctx, DataSource.class);

// アノテーション付き Bean
Map beans = ctx.getBeansWithAnnotation(Service.class);

方法3: Spring Boot Actuator の /beans

本番環境でも安全に Bean 一覧を見られる方法。spring-boot-starter-actuator を依存に追加:



    org.springframework.boot
    spring-boot-starter-actuator
# application.properties
management.endpoints.web.exposure.include=beans,health,env,mappings
management.endpoint.beans.enabled=true

# セキュリティ: 内部 IP のみ許可することを忘れず
management.server.port=9000
# curl で叩く
curl http://localhost:8080/actuator/beans | jq

# 出力例
{
  "contexts": {
    "application": {
      "beans": {
        "userService": {
          "aliases": [],
          "scope": "singleton",
          "type": "com.example.UserServiceImpl",
          "resource": "...",
          "dependencies": ["userRepository", "passwordEncoder"]
        }
      }
    }
  }
}

方法4: @PostConstruct でフィールドをログ出力

起動直後に Bean の状態をログに出すパターン。設定値の確認に便利:

@Service
@Slf4j
public class MailService {
    @Value("${spring.mail.host}")
    private String host;

    @Value("${spring.mail.port}")
    private int port;

    @Value("${spring.mail.username}")
    private String username;

    @PostConstruct
    public void init() {
        log.info("MailService 設定: host={}, port={}, user={}",
            host, port, username);
        // パスワードはログに出さない!
    }
}

方法5: Jackson で JSON 化

Lombok の @ToString で出ない循環参照を避けつつフィールドを見たい場合:

@Autowired
private ObjectMapper objectMapper;

@GetMapping("/debug/bean-json/{name}")
public String dump(@PathVariable String name) throws Exception {
    Object bean = ctx.getBean(name);
    return objectMapper.writerWithDefaultPrettyPrinter()
        .writeValueAsString(bean);
}

// 循環参照が出る場合
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

方法6: IDE デバッガ(最強)

IntelliJ IDEA / Eclipse / VS Code でブレークポイントを設定し、変数ウィンドウで Bean をインスペクト。プロキシ越しの場合は:

  • IntelliJ: Evaluate ExpressionAopUtils.getTargetClass(bean)((Advised) bean).getTargetSource().getTarget() を実行
  • Lazy Loading: 遅延初期化 Bean は最初のアクセスまで未生成 → ctx.getBean() でトリガー
  • CGLIB プロキシ: フィールドはターゲット側にある → 「View as: TargetSource」

方法7: DevTools の Live Reload

開発中なら spring-boot-devtools を入れると、コード変更で自動再起動 + Bean 一覧を VS Code Spring Boot Dashboard で可視化:


    org.springframework.boot
    spring-boot-devtools
    runtime
    true

方法比較

方法本番可動的手間
ApplicationContext#getBean△ デバッグ用 endpoint で隠す
Actuator /beans◯ セキュリティ設定すれば
@PostConstruct ログ×(起動時のみ)
Jackson JSON 化
IDE デバッガ×(リモートデバッグなら可)
DevTools Dashboard×

注意: 機密フィールドはマスクする

// パスワード / APIキー / トークンは Jackson で除外
public class DataSourceConfig {
    private String url;
    private String username;

    @JsonIgnore  // ← JSON 出力時に除外
    private String password;
}

// Lombok @ToString でも除外
@ToString(exclude = "password")
public class User {
    private String name;
    private String password;
}

FAQ

Q: NoSuchBeanDefinitionException が出る
A: Bean 名のタイポ、もしくは @Component / @Service 付け忘れ。@ComponentScan のパッケージ範囲も確認。

Q: Actuator は本番で開けて大丈夫?
A: Spring Security でアクセス制限を必ずかけてください。management.server.port を別ポートにして内部 LAN のみ許可が定番。

Q: 循環依存で Bean 生成が失敗する
A: setter 注入 / @Lazy で回避。設計を見直すのが本筋。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. プラットホーム
  2. 環境構築
  3. 文法
  4. API
  5. Servlet(サーブレット)
  6. JSP
  7. Applet(アプレット)
  8. デザインパターン
  9. フレームワーク
  10. ライブラリ
  11. Androidアプリケーション
  12. Project Jigsaw
  13. エラー一覧
  14. 日付の加算、減算
  15. 文字列の数字チェック
  16. 改行コードの削除
  17. 先頭と末端の文字の削除
  18. warファイルの中身を確認する方法
  19. nullもしくは空文字の判定
  20. beanの中身を確認する方法
  21. org.apache.log4j.Logger のログ出力で printStackTrace() のエラー内容を出力する方法
  22. Javaのバージョン確認方法