关于spring切面使用<aop:aspectj-autoproxy/>报错的解决方法
2013-06-09 15:02
871 查看
最近项目里需要加一些系统非业务功能,和一些框架外的地方性拓展。为此我们想到使用spring的切面方式进行增加。考虑到aspectj使用起来比较简单,而且以前也有使用的经验,因此决定还是采用它。可悲剧的是当我们将其加上后,项目在启动阶段就报错了。
环境:项目使用的是struts2+spring2.5+hibernate3
1.当开始报错后,我们将所有相关代码注释掉,单单加上<aop:aspectj-autoproxy/>的配置后,项目就报错了,虽然不同,主要报对象的循环注入问题,在度娘上找了好久给出的答案为:spring的2.X版本中可能存在这类问题,解决方法一般为:
a.升级spring的版本为新的版本,有人说是由于spirng的早期框架不够完善导致,没有采用该方案,由于项目比较大,不好轻易替换原有框架jar包。
b.覆盖spring的源码,报循环引用的错误,主要是由于容器中的setAllowRawInjectionDespiteWrapping默认设置为false导致,我们可以采用如下方式修改:
写一个自己的容器类,继承xmlwebapplicationcontext,然后将setAllowRawInjectionDespiteWrapping设置为true
public class AllowRawInjectDespisteWrappingApplicationContext extends
XmlWebApplicationContext {
protected DefaultListableBeanFactory createBeanFactory() {
DefaultListableBeanFactory beanFactory = super.createBeanFactory();
beanFactory.setAllowRawInjectionDespiteWrapping(true);
return beanFactory;
}
}
修改web.xml配置文件,增加容器参数:
<context-param>
<param-name>contextClass</param-name>
<param-value>com.jb.framework.AllowRawInjectDespisteWrappingApplicationContext</param-value>
</context-param>
完成上述操作后,确实不在报循环引用的错误了。但是将系统其它实例加进去后,还是报错。
2.主要报错为,不能为子类做代理,原因是说没有一个无参的构造函数,经检查发现,我们的被代理对象全部都含有默认的构造函数,而且错误日志中提示的类名$proxy32也不是我们系统中的类。无奈下,通过跟踪源码发现,当我们使用两种切面方式作用于同一个类时,就会出现这种错误,项目中事务管理我们采用过的是:
org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator而我们附加的功能采用的是:org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
当这两种方式同时生效时,会对一个类做2次或多次代理,这时就会出现上面的提示和错误。
既然知道了问题所在,那么解决起来就简单了,我们将事务管理的切片也改为了aspectj的方式来实现,至此问题解决。
环境:项目使用的是struts2+spring2.5+hibernate3
1.当开始报错后,我们将所有相关代码注释掉,单单加上<aop:aspectj-autoproxy/>的配置后,项目就报错了,虽然不同,主要报对象的循环注入问题,在度娘上找了好久给出的答案为:spring的2.X版本中可能存在这类问题,解决方法一般为:
a.升级spring的版本为新的版本,有人说是由于spirng的早期框架不够完善导致,没有采用该方案,由于项目比较大,不好轻易替换原有框架jar包。
b.覆盖spring的源码,报循环引用的错误,主要是由于容器中的setAllowRawInjectionDespiteWrapping默认设置为false导致,我们可以采用如下方式修改:
写一个自己的容器类,继承xmlwebapplicationcontext,然后将setAllowRawInjectionDespiteWrapping设置为true
public class AllowRawInjectDespisteWrappingApplicationContext extends
XmlWebApplicationContext {
protected DefaultListableBeanFactory createBeanFactory() {
DefaultListableBeanFactory beanFactory = super.createBeanFactory();
beanFactory.setAllowRawInjectionDespiteWrapping(true);
return beanFactory;
}
}
修改web.xml配置文件,增加容器参数:
<context-param>
<param-name>contextClass</param-name>
<param-value>com.jb.framework.AllowRawInjectDespisteWrappingApplicationContext</param-value>
</context-param>
完成上述操作后,确实不在报循环引用的错误了。但是将系统其它实例加进去后,还是报错。
2.主要报错为,不能为子类做代理,原因是说没有一个无参的构造函数,经检查发现,我们的被代理对象全部都含有默认的构造函数,而且错误日志中提示的类名$proxy32也不是我们系统中的类。无奈下,通过跟踪源码发现,当我们使用两种切面方式作用于同一个类时,就会出现这种错误,项目中事务管理我们采用过的是:
org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator而我们附加的功能采用的是:org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
当这两种方式同时生效时,会对一个类做2次或多次代理,这时就会出现上面的提示和错误。
既然知道了问题所在,那么解决起来就简单了,我们将事务管理的切片也改为了aspectj的方式来实现,至此问题解决。
相关文章推荐
- SPRING IN ACTION 第4版笔记-第四章ASPECT-ORIENTED SPRING-005-定义切面使用@Aspect、@EnableAspectJAutoProxy、<aop:aspectj-autoproxy>
- Spring AOP的实现原理之<aop:aspectj-autoproxy />的解析
- <aop:aspectj-autoproxy/>
- <aop:aspectj-autoproxy />作用
- spring中配置<aop:aspectj-autoproxy/>与<mvc:annotation-driven/>作用以及国际化配置
- 使用struts2的<s:param>等标签向action传值出现中文乱码的解决方法
- Spring配置项之<aop:aspectj-autoproxy />
- <aop:aspectj-autoproxy />作用
- Spring AOP的实现原理之<aop:aspectj-autoproxy />的解析
- <aop:aspectj-autoproxy proxy-target-class="false"/>导致出现404状态码
- Spring三种切面 <aop:aspectj-autoproxy/><aop:config></aop:config> <aop:scoped-proxy/>
- spring 配置 <aop:aspectj-autoproxy expose-proxy=""/>
- Spring配置---<aop:aspectj-autoproxy />
- spring添加<aop:aspectj-autoproxy>让注解自为类生成代理对象时出错
- JSP 中使用<%@include%> 报 Duplicate local variable path 错误的解决方法
- Spring配置项之<aop:aspectj-autoproxy />
- 使用<jsp:include>,不想写死URL,动态生成URL的解决的方法
- spring配置文件加<aop:aspectj-autoproxy/>后无法启动listener【解决方案】
- 使用<a>标签提交action会执行两次后台方法的原因(反射机制小实例问题的解决)
- Spring配置项之<aop:aspectj-autoproxy />