spring-aop - Spring Aspect 递归调用

标签 spring-aop aspect

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

最佳答案

我使用注释来更流畅:

@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;
}

在您想要尝试多次运行获取注释的方法上,您需要声明多少次(在我的例子中是 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-aop - Spring Aspect 递归调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23137623/

相关文章:

java - Spring @Transactional 在一个方面(AOP)

java - 如何测试我的异步进程是否已正确提交?

java - Spring Aop 依赖关系

java - 如何在 MethodInterceptor 中访问 SecurityContext?

java - Spring AOP BeanCreationException 由于 "formal unbound in pointcut"

java - AspectJ AOP LTW 不适用于 javaagent 的动态加载

java - aspectj 中的同步切入点

java - 切入点与继承的混淆

java - 在spring项目中添加aspect后出现UnsatisfiedDependencyException

java - Swing 面板/框架中的布局组件作为一个方面