Spring Aspect 递归调用

Posted

技术标签:

【中文标题】Spring Aspect 递归调用【英文标题】:Spring Aspect recursion call 【发布时间】:2014-04-17 15:44:52 【问题描述】:

我必须创建方面,应该在抛出自定义异常后再次调用具有相同参数的方法,该异常被抛出,但方法递归调用不能超过 5 次。有没有可能做到这一点?

【问题讨论】:

是什么引发了异常?建议还是建议的方法?只需创建一个最多循环 5 次的 @Around 建议,调用建议的方法。 【参考方案1】:

我用注解更流畅:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
/** Annotation for ascect using to define how many times try running     annotated method */

public @interface TryMultiplyTimes 
    /** define how many time try running method */
    int times() default 0;

在你想尝试多次运行 get 注释的方法上,声明你需要多少次(在我的例子中是 DAO 类):

@Component
public class CustomerDAOImpl

@TryMultiplyTimes(times=5)
public void addCustomerThrowException(String text) throws Exception 
    System.out.println("addCustomerThrowException() is running with args: "+text);
    throw new Exception("Generic Error");

还有最重要的部分:方面。我的方面基于注释周围尝试调用方法。 Aspect 尝试调用方法,当得到异常时,检查是否可以多次调用方法;如果不是,则例外。键是类和方法的hashCode,用来区分不同实体调用同一个方法。

@Aspect
public class MultiTimesAspect 

@Around("@annotation(multiTimeAnnotation)")
public void aspectMultiTime(ProceedingJoinPoint joinPoint, TryMultiplyTimes multiTimeAnnotation)throws Throwable 

    System.out.println("***********************************************");
    System.out.println("before running method: "+ joinPoint.getSignature().getName());

    try 
        joinPoint.proceed(joinPoint.getArgs()); //running method with it's args
     catch (Throwable e) 
        //if method throws exception:
        int times = multiTimeAnnotation.times();//get how many times can trying
        String key = createKey(joinPoint);      //create key (class hashCode and method hashCode) for managing map 
        if (repeatsMap.get(key) == null) 
            repeatsMap.put(key, 1);             //if method called first time
        

        int proceeded = repeatsMap.get(key);
        if (proceeded < times) 
            //if can try more times preincrement reapeats and recursively call aspect
            repeatsMap.replace(key, ++proceeded);
            aspectMultiTime(joinPoint, multiTimeAnnotation);
         else 
            //if can't call method anymore, delete from map key and throws excetion
            repeatsMap.remove(key);
            throw e;
        

    

    System.out.println("after running method: " + joinPoint.getSignature().getName());
    System.out.println("***********************************************");


private String createKey(JoinPoint joinPoint) 
    StringBuffer buffer = new StringBuffer();
    buffer.append(joinPoint.getTarget().toString()).append(".")
            .append(joinPoint.getThis().toString());
    return buffer.toString();


和测试类

public class Test 

public static void main(String... args)
    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
            "spring-aop.xml");
    CustomerDAOImpl customer= (CustomerDAOImpl) ctx.getBean("customerBo");
    try 
        customer.addCustomerThrowException("**TEST**");
     catch (Exception e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
    


【讨论】:

以上是关于Spring Aspect 递归调用的主要内容,如果未能解决你的问题,请参考以下文章

递归调用后的代码递归

递归调用太深,可能导致栈溢出

函数-递归调用

matlab 递归调用例子

函数的递归

OC中如何实现递归调用。