Spring 開發中,異常堆疊往往比文檔更誠實。本文彙總 18 類高頻錯誤,按依賴注入、配置元數據、類型轉換、AOP 代理、事務整合五大維度分類,附帶根因分析與修復代碼,助你快速定位、徹底解決。
NotWritablePropertyException —— 缺少 Setter 方法Error creating bean with name 'helloServiceImpl'...
Invalid property 'helloDao'... Bean property 'helloDao' is not writable or has an invalid setter method.
根因:Service 類聲明了 private HelloDao helloDao; 但未提供 setHelloDao()。Spring 基於 Setter 注入,屬性必須可寫。
修復:補全 Setter:
public void setHelloDao(HelloDao helloDao) {
this.helloDao = helloDao;
}
org.xml.sax.SAXParseException: Open quote is expected for attribute "scope"
根因:<bean scope=prototype> 缺少雙引號。XML 規範要求屬性值必須用引號包裹。
修復:<bean scope="prototype">
No bean named 'helloServiceImp' is defined
根因:context.getBean("helloServiceImp") 少寫一個 "l",配置文件中為 helloServiceImpl。
修復:IDE 重構重命名、或使用常量定義 Bean ID。
Cannot resolve reference to bean 'helloDaoImp' while setting bean property 'helloDao'
根因:spring-service.xml 引用 ref="helloDaoImp",但 spring-dao.xml 定義為 id="helloDaoImpl"。
修復:統一 ID 命名規範,跨文件引用時複製粘貼 ID。
Cannot find class [www.csdn.spring.dao.imp.HelloDaoImpl]... ClassNotFoundException
根因:配置 class="www.csdn.spring.dao.imp.HelloDaoImpl",實際類在 dao.impl 包下。
修復:核對 class 屬性與實際類路徑一致。
UnsatisfiedDependencyException: Ambiguous constructor argument types - did you specify the correct bean references?
根因:類屬性 private double salary;(基本類型),配置卻用 <constructor-arg type="java.lang.Double">(包裝類型)。構造器類型匹配不支援自動拆裝箱。
修復:類型完全一致:
<constructor-arg type="double" value="5000.00"/> // 基本類型
或
<constructor-arg type="java.lang.Double" value="5000.00"/> // 類屬性改為 Double
ConversionNotSupportedException: Cannot convert value of type [java.lang.String] to required type [Member]
根因:<property name="member" value="null"/> 將字符串 "null" 注入對象屬性。
修復:使用專用 <null/> 標籤:
<property name="member"><null/></property>
byType/constructor 自動裝配發現多個候選 BeanNoUniqueBeanDefinitionException: expected single matching bean but found 2: deptBean,deptBean1
根因:容器中存在多個同類型 Bean(DeptBean),自動裝配無法確定唯一候選者。
修復方案:
byName 或顯式 ref 引用@Primary(註解配置)或 primary="true"(XML)<property> 缺少 ref 或 valueConfiguration problem: <property> element for property 'users' must specify a ref or value
根因:集合屬性配置中註釋掉了所有注入方式(<list>、<array>、<util:list> 均被註釋),導致屬性無值。
修復:保留一種集合注入配置並取消註釋。
Bean named 'proxyFactoryBean' must be of type [SayServiceImpls], but was actually of type [$Proxy4]
根因:JDK 代理生成接口代理(返回接口類型),CGLIB 生成子類代理(返回類類型)。配置中目標類實現接口卻強制用 CGLIB,或混合使用導致類型不匹配。
修復:
<aop:config proxy-target-class="true"> 強制 CGLIBproxyInterfaces 設置為實現類而非接口IllegalArgumentException: [SayServiceImpl] is not an interface
修復:<value>www.csdn.spring.proxy.advice.SayService</value>(接口全限定名)
UnknownAdviceTypeException: Advice object [AuditableImpl] is neither a supported subinterface of Advice nor an Advisor
根因:自定義通知類(如前置通知)未實現 MethodBeforeAdvice 等標準接口。
標準通知接口對照表:
| 通知類型 | 實現接口 |
|---|---|
| 前置通知 | MethodBeforeAdvice |
| 後置通知 | AfterReturningAdvice |
| 環繞通知 | MethodInterceptor |
| 異常通知 | ThrowsAdvice |
| 引入通知 | DelegatingIntroductionInterceptor |
ClassCastException: $ProxyXX cannot be cast to ...常見原因:
@Aspect 註解修復:檢查 <aop:aspectj-autoproxy proxy-target-class="true"/>、確認 @Aspect 註解、核對類路徑。
<aop:aspect> 缺少 ref 屬性Configuration problem: <aspect> tag needs aspect bean reference via 'ref' attribute
修復:<aop:aspect ref="adviceService">
NamedParameterJdbcTemplate Bean 定義循環引用Could not resolve matching constructor... specify index/type/name arguments
根因:<property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"/> 自己引用自己。
修復:正確注入到 DAO:
<bean id="deptDaoImpl" class="...">
<property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"/>
</bean>
HibernateException: 'hibernate.dialect' must be set when no Connection available
根因:數據源配置錯誤(驅動類名、URL、用戶名密碼)導致無法獲取連接,Hibernate 無法自動檢測方言。
修復:
jdbc.properties 中驅動類名拼寫:oracle.jdbc.driver.OracleDriver<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>${hibernate.driverClassName} vs ${jdbc.driverClassName}java.lang.IllegalArgumentException: node to traverse cannot be null!
常見 HQL 寫法錯誤:
from 寫成 formset a=1 and b=2 應為 set a=1, b=2(逗號分隔)核心原則:拼寫一致性 > 複雜邏輯。絕大多數 Spring 錯誤源於 ID 拼寫、類型不匹配、配置缺失等基礎疏漏。