All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.easyretry.extension.spring.aop.RetryInterceptor Maven / Gradle / Ivy

The newest version!
package com.alibaba.easyretry.extension.spring.aop;

import java.lang.reflect.Method;
import java.util.Objects;

import com.alibaba.easyretry.common.RetryConfiguration;
import com.alibaba.easyretry.common.RetryIdentify;
import com.alibaba.easyretry.common.retryer.Retryer;
import com.alibaba.easyretry.core.RetryerBuilder;
import com.alibaba.easyretry.extension.spring.SPELResultPredicate;

import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.ApplicationContext;

@Aspect
public class RetryInterceptor {

	@Setter
	private RetryConfiguration retryConfiguration;

	@Setter
	private ApplicationContext applicationContext;

	@Around("@annotation(retryable)")
	public Object around(ProceedingJoinPoint invocation, EasyRetryable retryable) throws Throwable {
		if (RetryIdentify.isOnRetry()) {
			return invocation.proceed();
		}

		Retryer retryer = determineTargetRetryer(invocation, retryable);
		return retryer.call(invocation::proceed);
	}

	private String getBeanId(Class type) {
		String[] names = applicationContext.getBeanNamesForType(type);
		return names.length > 0 ? names[0] : null;
	}

	private Retryer determineTargetRetryer(ProceedingJoinPoint invocation, EasyRetryable retryable) {
		MethodSignature signature = (MethodSignature)invocation.getSignature();
		RetryerBuilder retryerBuilder = new RetryerBuilder()
			.withExecutorName(getBeanId(signature.getDeclaringType()))
			.withExecutorMethodName(signature.getMethod().getName())
			.withArgs(invocation.getArgs())
			.withConfiguration(retryConfiguration)
			.withReThrowException(retryable.reThrowException());
		if (StringUtils.isNotBlank(retryable.resultCondition())) {
			retryerBuilder.withResultPredicate(new SPELResultPredicate<>(retryable.resultCondition()));
		}

		return retryerBuilder.build(retryable.retryType());
	}
}