众所周知, 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依赖, 问题解决