はじめに
Spring Boot 3.xへの移行後、Claude Codeに書かせたコードがビルドエラーになるケースが増えている。javax.persistence.*のインポートやWebSecurityConfigurerAdapterの継承はSpring Boot 3.xではコンパイルすら通らない。CLAUDE.mdとPostToolUseフックを組み合わせれば、古いコードの混入を防げる。
Claude Codeが生成しやすい古いSpring Bootパターンを正す
`javax.*`から`jakarta.*`への名前空間移行
Spring Boot 3.0からJakarta EE 9ベースになり、JPA・バリデーション・サーブレット系パッケージがjakarta.*に変わった。
// ❌ Spring Boot 2.x
import javax.persistence.Entity;
import javax.validation.constraints.NotBlank;
import javax.servlet.http.HttpServletRequest;
// ✅ Spring Boot 3.x
import jakarta.persistence.Entity;
import jakarta.validation.constraints.NotBlank;
import jakarta.servlet.http.HttpServletRequest;
javax.sql.*・javax.crypto.*はJava SEのパッケージのため変更不要だ。全て置き換えると逆にエラーになる。
`WebSecurityConfigurerAdapter`の廃止
Spring Security 6(Spring Boot 3同梱)ではWebSecurityConfigurerAdapterが完全削除された。
// ❌ Spring Boot 2.x(Spring Boot 3でコンパイルエラー)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/public/**").permitAll()
.anyRequest().authenticated().and().formLogin().and().csrf().disable();
}
}
// ✅ Spring Boot 3.x
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(a -> a.requestMatchers("/public/**").permitAll().anyRequest().authenticated())
.formLogin(f -> f.loginPage("/login").permitAll())
.csrf(c -> c.disable()).build();
}
}
`@Autowired`フィールドインジェクション→コンストラクターインジェクション
// ❌ フィールドインジェクション
@Service
public class OrderService {
@Autowired private OrderRepository repo;
@Autowired private PaymentGateway gateway;
}
// ✅ コンストラクターインジェクション(Lombok)
@Service
@RequiredArgsConstructor
public class OrderService {
private final OrderRepository repo;
private final PaymentGateway gateway;
}
@RequiredArgsConstructorでfinalフィールドのコンストラクターが自動生成される。
CLAUDE.mdで制御する完全テンプレート
# Spring Boot 3.x ルール
- インポート: jakarta.* を使う(javax.persistence.* / javax.validation.* / javax.servlet.*)
例外: javax.sql.* / javax.crypto.* はJava SEのため変更なし
- DI: @Autowired フィールドDI禁止 → コンストラクター + @RequiredArgsConstructor
- Security: WebSecurityConfigurerAdapter 禁止(削除済み)→ SecurityFilterChain @Bean
ラムダDSL必須。.and() / antMatchers() / authorizeRequests() 禁止
- HTTP: new RestTemplate() 禁止 → RestClient(同期)/ WebClient(非同期)
- JPA: JpaRepository<T, ID> を使う
- テスト: @MockBean 禁止(3.4以降非推奨)→ @MockitoBean
- Maven: ./mvnw が存在する場合はmvnwを使う
PostToolUseフックで非推奨パターンを自動検出する
Javaファイル編集後に非推奨パターンを検出するフックを設定する。
#!/bin/bash
# scripts/check-deprecated.sh
C=$(jq -r '.tool_input.content // empty')
echo "$C" | grep -qE "import javax\.(persistence|validation|servlet)" \
&& echo "ERROR: javax.* → jakarta.* を使ってください" && exit 1
echo "$C" | grep -q "WebSecurityConfigurerAdapter" \
&& echo "ERROR: WebSecurityConfigurerAdapter削除済み → SecurityFilterChain" && exit 1
echo "$C" | grep -q "boot\.test\.mock.*MockBean" \
&& echo "ERROR: @MockBean非推奨 → @MockitoBean" && exit 1
exit 0
{
"hooks": {
"PostToolUse": [{
"matcher": "Edit|Write",
"hooks": [{ "type": "command", "command": "bash scripts/check-deprecated.sh" }]
}]
}
}
EM視点──チームのSpring Boot標準をAIに守らせる
Spring Boot 3.x移行期にClaude Codeが古いパターンを生成するリスクは大きい。CLAUDE.mdをリポジトリにコミットすれば、個人の熟練度に関係なく全員のClaude Codeが同じルールで動く。CIにOpenRewriteのUpgradeSpringBoot_3_3レシピを組み込むと、AI生成コードも含めてjavax.*を機械的に検出できる。PostToolUseフックとCIの二重チェックでコードレビューの指摘を大幅に減らせる。
まとめ
Claude CodeがSpring Bootで生成しやすい古いパターンはjavax.*インポート・WebSecurityConfigurerAdapter・@Autowiredフィールドインジェクションだ。本記事のCLAUDE.mdテンプレートを今すぐプロジェクトにコミットしてほしい。PostToolUseフックを合わせて設定すれば、古いコードが混入した瞬間にClaude Codeが自己修正する。

コメント