关于Spring增强器定义顺序引起的问题
2016-11-28 11:23
204 查看
1 问题
org.springframework.beans.factory.BeanCreationException: Error creating bean with name'chat' defined in ServletContext resource[/WEB-INF/applicationContext_lease.xml]: Initialization of bean failed;nestedexception is java.lang.IllegalArgumentException: Advice precedence circularityerror
atorg.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at
...
Causedby: java.lang.IllegalArgumentException: Advice precedence circularityerror
atorg.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.sortAdvisors(AspectJAwareAdvisorAutoProxyCreator.java:82)
atorg.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:90)
... 20 more
2 原因分析
反编译PartialOrder,发现只有在“List sort(Listobjects)”返回空时才会报错。 这个方法的作用是对增强器进行排序,排序的算法是从列表中每次查找最小值,把最小值写入objects的相应位置,然后重复该过程。查找最小值的算法是:先通过循环比较为每个增强器设置smallerObjects和biggerObjects两个列表,然后查找smallerObjects内容为空的。当查找最小增强器失败时,即所有增强器的smallerObjects都不为空时,就会返回null,从而导致上述异常。
所有增强器的比较规则(AspectJPrecedenceComparator):
1) 两个增强一个是after一个是before,那么返回0(相等)
2) 当其中一个是after时,按declareOrder进行比较,a1<a2,返回1,a1>a2,返回-1;(排在前面的大)
3) 不满足上面两个条件的,按declareOrder进行比较,a1<a2,返回-1,a1>a2,返回1。(排在后面的大)
declareOrder是clazz.getDeclaredMethod返回的方法的自然顺序,这个顺序在不同的jdk(编译、运行都有关)下是不同的,且在java的文档中明确说明返回的方法数组没有排序,也不承诺任何特别的顺序。
这样一来,比如有下面一组增强器,在jdk1.7下的顺序declareOrder如下:
Around1 order:1
After1 order:2
Around2 order:3
按照比较规则:
Around1 smallerObjects: After1
After1 smallerObjects: Around2
Around2 smallerObjects: Around1
这样所有增强器的smallerObjects都不为空,无法找到最小值,从而导致以上异常。
3 解决办法
把增强器拆分到不同的Aspect类中,比如把Around、After、Before分别放入不同的类,这样declareOrder就只是同一个类型的增强器的,也就不会出现上面的问题。相关文章推荐
- 关于spring加载applicationContext初始化bean顺序的问题
- 关于博客园服务器升级到Windows 2003 SP 1引起的问题(都是SP 1惹的祸)
- 关于自己定义Page的一个小问题
- 关于初学ASP.NET技术的学习顺序问题
- 关于asp.net中ajax的问题:AjaxControlToolkit 未定义的解决方法
- 关于初学ASP.NET技术的学习顺序问题
- 关于spring+hibernate中的单元测试问题
- 学习类,笔记!关于一个函数里面定义多个类以及相互访问的问题
- iis和VS2005安装顺序引起的问题
- 关于引起stop:c000021a unknown hard error部分问题及解决。
- 关于C# using 作为定义范围的问题
- Spring的XML解析中关于DTD的路径问题-
- 由于struts配置文件没有定义头文件引起的问题
- 关于Spring的持久化问题.
- 关于由病毒引起的桌面图标丢失问题.
- 关于网络传输字节顺序的问题: hton? or ntoh?-
- 关于LINUX下JSP文件上传出现中文文件名 引起的问题
- 一些关于hibernate 与 spring 事务管理的问题
- 关于spring中处理相同id的bean的问题
- 转载:) 关于spring、hibernate、struts的一些错误问题 不断补充中(靠自己了)