把 Spring Boot 升到 4.x 再接 LangChain4j starter,應用起不來,掛在
ConfigurationClassPostProcessor階段,報Failed to generate bean name for imported class。這不是 Bean 實例化出錯,是設定類壓根沒註冊上。維護者討論過同一模塊難兼容 3.x 與 4.x,截至撰寫時適配仍在進行中。生產環境別硬升 4.x,先把 Spring Boot 鎖回 3.5.x。
Issue & Env(案發現場與環境)
- 業務場景:Spring Boot 項目引入 LangChain4j 的 starter,想靠自動設定拿到模型 Bean,一啟動就失敗。
- 環境:Spring Boot 4.0(對應 Spring Framework 7),LangChain4j starter 按 Spring Boot 3.x 的約定編譯,JDK 17+。
- 這裡以
langchain4j-open-ai-spring-boot-starter為例,報錯裡的設定類是dev.langchain4j.openai.spring.AutoConfig。
StackTrace(堆疊日誌)
報錯原文(來自 issue #4268):
Caused by: java.lang.IllegalStateException: Failed to generate bean name for imported class 'dev.langchain4j.openai.spring.AutoConfig'
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.registerBeanDefinitionForImportedConfigurationClass(ConfigurationClassBeanDefinitionReader.java:172)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:145)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:124)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:458)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:310)
Reproduce(復現程式碼)
用 Spring Boot 4 的父 POM,再引 starter:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.0</version>
</parent>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
</dependency>
只要 starter 在 classpath 上,哪怕還沒寫模型設定,啟動就會掛。
Root Cause(根因分析)
先看報錯的位置。調用棧是 ConfigurationClassPostProcessor,屬於 ApplicationContext refresh 的早期。這時還沒走到實例化 Bean,框架正在讀設定類。問題出在「讀取設定類」這一步,跟模型參數、API key 都無關。
Spring Boot 4 隨 Spring Framework 7 一起來。這一版對設定類處理和自動設定導入改動較大。LangChain4j starter 內部的 AutoConfig 仍按舊約定寫,在 Spring Boot 4 下無法被正常註冊為設定類,啟動直接失敗。
維護者討論(issue #4268):同一個 langchain4j-spring 模塊很難同時兼容 Spring Boot 3.x 與 4.x。討論過「同一模塊發兩個版本」的方向。具體工作在 langchain4j-spring PR #153,仍屬進行中。
一句話,截至撰寫時 Spring Boot 4 支持還沒修好,別當成已解決。
The Fix(解決方案)
短期最省事的做法是回退。把 Spring Boot 鎖回 3.x,和 starter 的編譯目標對齊:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.0</version>
</parent>
先確認依賴版本,再動手升級:
mvn dependency:tree -Dincludes=dev.langchain4j
./gradlew dependencies | grep -E "langchain4j|spring-boot"
看清 starter 的版本和 Spring Boot 的大版本。注意 Spring Boot 4 的 starter 座標與包名,在大版本之間也可能變。
盯緊 langchain4j-spring PR #153 的合入進度。生產上別硬升 Spring Boot 4。
如果非要在 Spring Boot 4 上跑,目前只能不用官方 starter,手動聲明模型 Bean:
@Configuration
public class ModelConfig {
@Bean
public OpenAiChatModel openAiChatModel() {
return OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4o-mini")
.build();
}
}
代價是丟掉自動設定的便利。這屬於 workaround,不推薦長期用。
小結
根子在版本。Spring Boot 4 改了設定類處理,LangChain4j starter 沒跟上。短期鎖回 3.5.x,長期等 PR #153。真要硬上 4.x,只能手寫 Bean。
