衆所周知, spring是一個大家族, 稍有不慎, 就有人罷工, 裏面的模塊依賴出現問題
簡單的還好, 複雜的, 真得找半天啊
下面說一個, 今天遇到和解決的問題.
程序啓動出現這樣的錯誤警告:
nested exception is java.lang.NoSuchMethodError: org.springframework.aop.config.AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(Lorg/springframework/beans/factory/xml/ParserContext;Ljava/lang/Object;)
經過查看spring4源碼, 這個方法確實不存在 (存在同名, 但是參數類型不同的方法)
但是spring3存在, 已經標明爲Deprecated
網上找了半天, 各種方法都試了, 不行
就是一個過時的方法啊, 現在好了, 必須要用到這個方法 (當時認爲問題在這裏)
後來發現, 只要在spring配置文件裏面 去掉 tx:annotation-driven , 就不會出現這個問題了
我首先嚐試了 使用 自己編寫 aop 的advice 和 pointcut 來解決 :
將
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
改爲
<tx:advice id="jpaAdvice" transaction-manager="transactionManager" />
<aop:config>
<aop:advisor advice-ref="jpaAdvice" pointcut="within(XXX.db.service..*)" />
</aop:config>
運行報這個問題
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'deviceDao': Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.springframework.transaction.interceptor.TransactionInterceptor.setTransactionManagerBeanName(Ljava/lang/String;)V
我以爲沒解決問題, 繼續找方法, 還是沒找到
後來嘗試黑科技, 直接覆蓋spring的這個類 org.springframework.aop.config.AopNamespaceUtils
加上了我需要的方法
registerAutoProxyCreatorIfNecessary(org.springframework.beans.factory.xml.ParserContext, java.lang.Object)
(方法從spring3拷貝而來)
結果運行, 還是這個錯誤
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'deviceDao': Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.springframework.transaction.interceptor.TransactionInterceptor.setTransactionManagerBeanName(Ljava/lang/String;)V
我就明白了, 錯誤不在最開始的地方, 而是在這裏
我使用IDEA 查找類 :
org.springframework.transaction.interceptor.TransactionInterceptor
結果有兩個!!!
這應該高度注意了, 肯定是衝突纔有兩個同一類名的
1 spring-tx 有需要的方法 (在父類)
2 spring-dao 裏面, 是沒有需要的方法
經過檢查, 發現不小心將spring-dao 加進來了, spring-dao 覆蓋 spring-tx
刪掉spring-dao依賴, 問題解決