Spring AOP - 多个拦截器不能一起工作

时间:2016-04-22 12:03:24

标签: java spring spring-aop

我想将建议应用于方法helloWorld。我想限制超过' x' TPS并重试这些电话。

所以我有2个拦截器 -

  1. 节流拦截器,限制呼叫率超过&#39; <&#39;
  2. 重试拦截器,如果调用被限制则重试。
  3.   

    问题在于,当我将两个拦截器组合在一起时,节流   即使我将Rate设置为0,拦截器似乎也不起作用,即helloWorld方法被执行。

         

    如果我只是   使用限制拦截器它工作正常。

    我的Spring Configuration是这样的。

    <bean id="retryPolicy" class="xyz.RetryPolicyFactoryBean">
        <property name="backoffCoefficient"><value>2</value></property>
        <property name="multiplierMillis"><value>100</value></property>
        <property name="maxDelayMillis"><value>2000</value></property>
        <property name="maxAttempts"><value>2</value></property>
        <property name="expirationDurationMillis"><value>60000</value></property>
    
    <bean id="retryInterceptor" class="xyz.RetryInterceptor">
    <constructor-arg index="0"><ref bean="retryPolicy"/></constructor-arg> 
    </bean>
    
    <bean id="throttlingInterceptor" class="xyz.ThrottlingInterceptor">
        <constructor-arg index="0"><value>key</value></constructor-arg> 
    </bean>
    
    <bean id="helloWorld" class="xyz.helloWorld" />
    
    <bean id="helloWorldProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="helloWorld" />
        <property name="interceptorNames">
            <list>
                <value>retryInterceptor</value>
                <value>throttlingInterceptor</value>
            </list>
        </property>
    </bean>
    

    Throttling Interceptor是这样的:

    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        if (isDecorated(methodInvocation)) {
            if (throttler.isThrottled(key)) {
    
                throw new ThrottlingException("Call throttled.");
            }
        }
        return methodInvocation.proceed();
    }
    

    我的retry interceptor是这样的:

    public class RetryInterceptor extends RetryAdvice {
    
    public RetryInterceptor(RetryPolicy retryPolicy) {
        super(retryPolicy);
    }
    
    @Override
    public Object invoke(final MethodInvocation methodInvocation) throws Throwable {
        return super.invoke(methodInvocation);
    }
    

    我在这里缺少什么?

1 个答案:

答案 0 :(得分:0)

我使用了AspectJ Annotations&amp; amp;让它工作(至少现在正在调用拦截器)。

使用@Aspect

注释包含建议的类

这是我的节气门建议:

@Before(pointcut="execution(* com.company.xyz.method())")
public void invoke() throws ThrottlingException {
    if (throttler.isThrottled(throttleKey)) {
        throw new ThrottlingException("Call Throttled");
    }
}

我的重试拦截器:

@AfterThrowing(pointcut="execution(* com.company.xyz.method())", throwing="exception")
public Object invoke(JoinPoint jp, ThrottlingException exception) throws Throwable {
return RetryingCallable.newRetryingCallable(new Callable<Object>() {

    @Override
    public Object call() throws Exception {
            MethodSignature  signature = (MethodSignature) p.getSignature();
            Method method = signature.getMethod();
            return method.invoke(jp.getThis(), (Object[]) null);
    }

}, retryPolicy).call();

}

相关Spring配置

<bean id="retryInterceptor" class="com.company.xyz.RetryInterceptor">
<constructor-arg index="0"><ref bean="retryPolicy"/></constructor-arg> 
</bean>


<bean id="throttlingInterceptor" class="com.company.xyz.ThrottlingInterceptor">
<constructor-arg><value>throttleKey</value></constructor-arg> 
</bean>

<aop:aspectj-autoproxy/>

需要注意的另一点是调用拦截器的Order。使用@Order Annotation确保订单。