今天做项目的时候,由于要用到在Struts2的Action类中利用Spring的AOP来实现记录操作日志,在Action里面的方法中加上自定义annotation来实现记录操作功能,运行的时候页面提示NoSuchMethodException when Aspec,网上说是Action继承了ActionSupport导致的,后来在一个英文网站上找到了解决的方法,只要在Spring的配置文件applicationContext中的<aop:aspectj-autoproxy/>改为<aop:aspectj-autoproxy proxy-target-class="true"/>就可以了。
英文网站的地址是:http://forum.springsource.org/showthread.php?t=51758,原文如下:
<!-- / icon and title --><!-- message -->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd" default-lazy-init="true"> <!-- =================================================================== --> <!-- AOP: Configuration and Aspects --> <!-- =================================================================== --> <aop:config> <aop:advisor id="userManagerTx" advice-ref="userManagerTxAdvice" pointcut="execution(* *..service.UserManager.*(..))" order="0"/> <aop:advisor id="userManagerSecurity" advice-ref="userSecurityAdvice" pointcut="execution(* *..service.UserManager.saveUser(..))" order="1"/> <aop:advisor id="managerTx" advice-ref="txAdvice" pointcut="execution(* *..service.*Manager.*(..))" order="2"/> </aop:config> <!-- Enable @Transactional support --> <tx:annotation-driven/> <!-- Fix bug in Spring 2.0.6: http://issues.appfuse.org/browse/APF-887 --> <bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect" factory-method="aspectOf" dependency-check="none" lazy-init="false"> <property name="transactionManager" ref="transactionManager"/> </bean> <!-- Enable @AspectJ support --> <aop:aspectj-autoproxy/> <!-- Enable @Configured support --> <aop:spring-configured/> <tx:advice id="txAdvice"> <tx:attributes> <!-- Read-only commented out to make things easier for end-users --> <!-- http://issues.appfuse.org/browse/APF-556 --> <!--tx:method name="get*" read-only="true"/--> <tx:method name="*"/> </tx:attributes> </tx:advice> <tx:advice id="userManagerTxAdvice"> <tx:attributes> <tx:method name="save*" rollback-for="UserExistsException"/> </tx:attributes> </tx:advice> <bean id="userSecurityAdvice" class="org.appfuse.service.UserSecurityAdvice"/> [...]
<bean id="aLogInterceptor" class="com.bungee.aspects.AnnotationLoggerInterceptor" /> <bean id="cpLogInterceptor" class="com.bungee.aspects.PackagesLoggerInterceptor" />
@Aspect public class PackagesLoggerInterceptor { @Before( "execution( * com.bungee..*.*(..) ) && !execution( * com.bungee.aspects.*.*(..) )" ) public void beforeMethod( JoinPoint jp ) { // logging in here } @AfterReturning( pointcut = "execution( * com.bungee..*.*(..) ) && !execution( * com.bungee.aspects.*.*(..) )", returning="retVal" ) public void afterMethod( JoinPoint jp, Object retVal ) { // more logging in here... } @AfterThrowing( pointcut = "execution( * com.bungee..*.*(..) ) && !execution( * com.bungee.aspects.*.*(..) )", throwing="ex" ) public void afterException( JoinPoint jp, Throwable ex ) { // ... and finish logging here } }
java.lang.NoSuchMethodException: $Proxy361.initHome() at java.lang.Class.getMethod(Class.java:1605) at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.getActionMethod(AnnotationValidationInterceptor.java:55) at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:41) at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86) at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:123) at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:167) at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86) at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) [...]
@annotation( com.bungee.annotations.Loggeable )
<aop:aspectj-autoproxy proxy-target-class="true"/>