Spring AOP对嵌套方法不起作用

25 篇文章 1 订阅
6 篇文章 1 订阅

Spring AOP有一个限制,它对嵌套方法调用不起作用。究其原因,是因为Spring aop是作用在spring beans上,而不是作用于实际的类的实例。举例来说:

比如我按如下方法配置了一个aspect,

	<bean
		class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />

	<bean id="positionAspect"
		class="com.MyPositionUpdateAspect"/>


在这个aspect里(使用aspectj的语法支持),我配置了我的pointcut,意思是对MyTradeProcessor的所有方法调用(正常返回的)进行拦截。

package com;

@Aspect
public class MyPositionUpdateAspect {
	@AfterReturning(value = "execution(* com.MyTradeProcessor.*(..))", returning = "retTrade")
	public void updatePosition(JoinPoint joinPoint, Object retTrade) throws Throwable {
        // my business logic
        }
}

下面是MyTradeProcessor类的大致框架:

public class MyTradeProcessor {
        public ITrade amend(ITrade inputTrade) throws TradeBookingException {
            if (isAmendForTemp)
                return newTrade(inputTrade);
            }

            // other logic
        }

	public ITrade newTrade(ITrade inputTrade) throws TradeBookingException {
            // newTrade logic
        }
}


问题就出在amend方法里,如果某个条件成立,它会嵌套调用newTrade方法,按理说aop的拦截会触发两次,但是实际上它只会触发一次,就是调用amend方法时。当然,如果你直接调用newTrade方法,该方法的拦截会调用。原因就是上面提到的,因为当你在amend方法里调用newTrade方法时,你调用的是this实例,而这个不是spring里面配置的bean对象。所以有一个比较变态的解决办法是在这个类里在配置一个叫做self的bean,调用这个bean的newTrade方法。


还有一种解决办法是利用aspectj weaving。大致的配置如下,详细的说明可以参考http://stackoverflow.com/questions/5780757/spring-aop-logging-and-nested-methods

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">    
<aspectj>    
    <weaver options="-Xset:weaveJavaxPackages=true -verbose -showWeaveInfo -debug">    
        <include within="*"/>
    </weaver>
    <aspects>
        <!-- weave in just this aspect -->
        <aspect name="your.logger.impl.LoggingImpl"/>
    </aspects>
  </aspectj>
This implies weaving in all your files ('within=*', modify as you wish) with the aspect/s specified. On load time you should see verbose information on weaving of classes.
<context:load-time-weaver aspectj-weaving="autodetect" 

            weaver-class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"/>




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值