feat: 1.1.0

1. 添加部分代码注释
2. XRetry名称变更EasyRetry
3. RetryAspect添加Ordered,支持动态调整Aop执行顺序
This commit is contained in:
byteblogs168 2023-04-26 11:37:26 +08:00
parent 4f58b6d7ee
commit dceda7d5ad
16 changed files with 123 additions and 35 deletions

View File

@ -22,8 +22,10 @@ import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature; import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered; import org.springframework.core.PriorityOrdered;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -39,8 +41,7 @@ import java.util.UUID;
@Aspect @Aspect
@Component @Component
@Slf4j @Slf4j
@Order(PriorityOrdered.HIGHEST_PRECEDENCE + 2) public class RetryAspect implements Ordered {
public class RetryAspect {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static String retryErrorMoreThresholdTextMessageFormatter = private static String retryErrorMoreThresholdTextMessageFormatter =
@ -55,6 +56,8 @@ public class RetryAspect {
private RetryStrategy retryStrategy; private RetryStrategy retryStrategy;
@Autowired @Autowired
private AltinAlarmFactory altinAlarmFactory; private AltinAlarmFactory altinAlarmFactory;
@Autowired
private StandardEnvironment standardEnvironment;
@Around("@annotation(com.aizuda.easy.retry.client.core.annotation.Retryable)") @Around("@annotation(com.aizuda.easy.retry.client.core.annotation.Retryable)")
public Object around(ProceedingJoinPoint point) throws Throwable { public Object around(ProceedingJoinPoint point) throws Throwable {
@ -192,4 +195,11 @@ public class RetryAspect {
} }
return objMethod.getAnnotation(Retryable.class); return objMethod.getAnnotation(Retryable.class);
} }
@Override
public int getOrder() {
String order = standardEnvironment
.getProperty("easy-retry.aop.order", String.valueOf(Ordered.HIGHEST_PRECEDENCE));
return Integer.parseInt(order);
}
} }

View File

@ -25,6 +25,8 @@ import java.util.concurrent.TimeUnit;
import java.util.function.Function; import java.util.function.Function;
/** /**
* 上报服务端
*
* @author: www.byteblogs.com * @author: www.byteblogs.com
* @date : 2022-03-08 09:24 * @date : 2022-03-08 09:24
*/ */

View File

@ -15,9 +15,10 @@ import java.util.Base64;
import java.util.Objects; import java.util.Objects;
/** /**
* Hessian序列化
*
* @author: www.byteblogs.com * @author: www.byteblogs.com
* @date : 2022-03-07 15:08 * @date : 2022-03-07 15:08
* @date 2022/1/5 11:14 上午
*/ */
@Component("XRetryHessianSerializer") @Component("XRetryHessianSerializer")
public class HessianSerializer implements RetryArgSerializer { public class HessianSerializer implements RetryArgSerializer {

View File

@ -11,6 +11,8 @@ import java.lang.reflect.Method;
import java.lang.reflect.Type; import java.lang.reflect.Type;
/** /**
* Jackson序列化
*
* @author: www.byteblogs.com * @author: www.byteblogs.com
* @date : 2022-03-07 15:08 * @date : 2022-03-07 15:08
*/ */

View File

@ -7,6 +7,6 @@ import org.springframework.context.annotation.Configuration;
@Configuration @Configuration
@ComponentScan("com.aizuda.easy.retry.client.core") @ComponentScan("com.aizuda.easy.retry.client.core")
@ConditionalOnProperty(prefix = "easy-retry", name = "enabled", havingValue = "true") @ConditionalOnProperty(prefix = "easy-retry", name = "enabled", havingValue = "true")
public class XRetryClientAutoConfiguration { public class EasyRetryClientAutoConfiguration {
} }

View File

@ -10,18 +10,21 @@ import org.springframework.core.type.AnnotationMetadata;
import java.util.Map; import java.util.Map;
/** /**
* Easy Retry 客户端注册器
*
* @author: www.byteblogs.com * @author: www.byteblogs.com
* @date : 2022-03-04 18:44 * @date : 2022-03-04 18:44
*/ */
public class XRetryClientsRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware { public class EasyRetryClientsRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware {
private StandardEnvironment standardEnvironment; private StandardEnvironment standardEnvironment;
@Override @Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
Map<String, Object> attrs = importingClassMetadata.getAnnotationAttributes(EnableXRetry.class.getName()); Map<String, Object> attrs = importingClassMetadata.getAnnotationAttributes(EnableEasyRetry.class.getName());
Map<String, Object> systemEnvironment = standardEnvironment.getSystemProperties(); Map<String, Object> systemEnvironment = standardEnvironment.getSystemProperties();
systemEnvironment.put("easy-retry.group", (String) attrs.get("group")); systemEnvironment.put("easy-retry.group", attrs.get("group"));
systemEnvironment.put("easy-retry.aop.order", attrs.get("order"));
} }
@Override @Override

View File

@ -0,0 +1,38 @@
package com.aizuda.easy.retry.client.starter;
import org.springframework.context.annotation.Import;
import org.springframework.core.Ordered;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.lang.annotation.*;
/**
* 在启动类上添加EnableEasyRetry注解开启Easy Retry功能
*
* @author: www.byteblogs.com
* @date : 2021-12-31 18:45
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EasyRetryClientsRegistrar.class)
public @interface EnableEasyRetry {
/**
* 表示该重试数据属于哪个系统并且全局唯一
*
* @return
*/
String group();
/**
* 控制多个Aop的执行顺序,
* 需要注意的是这里顺序要比事务的Aop要提前
*
* see {@link EnableTransactionManagement#order()}
* 默认值: Ordered.HIGHEST_PRECEDENCE
*/
int order() default Ordered.HIGHEST_PRECEDENCE;
}

View File

@ -1,18 +0,0 @@
package com.aizuda.easy.retry.client.starter;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
/**
* @author: www.byteblogs.com
* @date : 2021-12-31 18:45
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(XRetryClientsRegistrar.class)
public @interface EnableXRetry {
String group();
}

View File

@ -1,2 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.aizuda.easy.retry.client.starter.XRetryClientAutoConfiguration com.aizuda.easy.retry.client.starter.EasyRetryClientAutoConfiguration

View File

@ -1,19 +1,19 @@
package com.example; package com.example;
import com.aizuda.easy.retry.client.starter.EnableXRetry; import com.aizuda.easy.retry.client.starter.EnableEasyRetry;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
//import org.springframework.cloud.netflix.feign.EnableFeignClients; //import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.Ordered;
import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication @SpringBootApplication
@EnableFeignClients(basePackages = "com.example.client") @EnableFeignClients(basePackages = "com.example.client")
@EnableXRetry(group = "example_group") @EnableEasyRetry(group = "example_group")
@EnableAspectJAutoProxy @EnableAspectJAutoProxy
//@EnableTransactionManagement(order = Ordered.LOWEST_PRECEDENCE - 10)
@EnableTransactionManagement @EnableTransactionManagement
public class ExampleApplication { public class ExampleApplication {

View File

@ -0,0 +1,22 @@
package com.example.demo;
import com.example.model.TransactionalEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
/**
* @author: shuguang.zhang
* @date : 2023-04-25 22:46
*/
@Component
@Slf4j
public class TestEventListener {
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT, fallbackExecution = true)
public void beforeConfirmSell(TransactionalEvent<String> event) {
log.info("触发beforeConfirmSell事件 [{}]", event);
}
}

View File

@ -1,9 +1,11 @@
package com.example.demo; package com.example.demo;
import com.aizuda.easy.retry.client.core.annotation.Retryable; import com.aizuda.easy.retry.client.core.annotation.Retryable;
import com.aizuda.easy.retry.common.core.context.SpringContext;
import com.aizuda.easy.retry.common.core.model.Result; import com.aizuda.easy.retry.common.core.model.Result;
import com.example.mapper.SchoolMapper; import com.example.mapper.SchoolMapper;
import com.example.mapper.StudentMapper; import com.example.mapper.StudentMapper;
import com.example.model.TransactionalEvent;
import com.example.po.School; import com.example.po.School;
import com.example.po.Student; import com.example.po.Student;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -53,6 +55,9 @@ public class TestExistsTransactionalRetryService {
throw new UnsupportedOperationException("调用远程失败" + school.getAddress()); throw new UnsupportedOperationException("调用远程失败" + school.getAddress());
} }
TransactionalEvent<String> event = new TransactionalEvent<>("123");
SpringContext.applicationContext.publishEvent(event);
return "testSimpleInsert"+school.getAddress(); return "testSimpleInsert"+school.getAddress();
} }

View File

@ -1,10 +1,12 @@
package com.example.demo; package com.example.demo;
import com.aizuda.easy.retry.client.core.annotation.Retryable; import com.aizuda.easy.retry.client.core.annotation.Retryable;
import com.aizuda.easy.retry.common.core.context.SpringContext;
import com.aizuda.easy.retry.common.core.model.Result; import com.aizuda.easy.retry.common.core.model.Result;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.mapper.SchoolMapper; import com.example.mapper.SchoolMapper;
import com.example.mapper.StudentMapper; import com.example.mapper.StudentMapper;
import com.example.model.TransactionalEvent;
import com.example.po.School; import com.example.po.School;
import com.example.po.Student; import com.example.po.Student;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -48,6 +50,9 @@ public class TestExistsTransactionalRetryService2 {
throw new UnsupportedOperationException("调用远程失败"); throw new UnsupportedOperationException("调用远程失败");
} }
TransactionalEvent<String> event = new TransactionalEvent<>("123");
SpringContext.applicationContext.publishEvent(event);
return "testSimpleInsert"+school.getAddress(); return "testSimpleInsert"+school.getAddress();
} }

View File

@ -0,0 +1,18 @@
package com.example.model;
import lombok.Getter;
import org.springframework.context.ApplicationEvent;
/**
* @author: shuguang.zhang
* @date : 2023-04-25 22:48
*/
@Getter
public class TransactionalEvent<T> extends ApplicationEvent {
private T data;
public TransactionalEvent(final T source) {
super(source);
}
}

View File

@ -39,7 +39,7 @@ public class ExistsTransactionalRetryServiceTest {
Mockito.when(remoteService.call()) Mockito.when(remoteService.call())
.thenReturn(new Result(0, "1")) .thenReturn(new Result(0, "1"))
.thenReturn(new Result(0, "2")) .thenReturn(new Result(0, "2"))
.thenReturn(new Result(0, "3")) .thenReturn(new Result(3, "3"))
.thenReturn(new Result(0, "4")) .thenReturn(new Result(0, "4"))
.thenReturn(new Result(0, "5")) .thenReturn(new Result(0, "5"))
; ;
@ -63,10 +63,10 @@ public class ExistsTransactionalRetryServiceTest {
.thenReturn(new Result(0, "2")) .thenReturn(new Result(0, "2"))
.thenReturn(new Result(0, "3")) .thenReturn(new Result(0, "3"))
.thenReturn(new Result(0, "4")) .thenReturn(new Result(0, "4"))
.thenReturn(new Result(0, "5")) .thenReturn(new Result(1, "5"))
; ;
try { try {
String s = testExistsTransactionalRetryService2.testSimpleUpdate(243L); String s = testExistsTransactionalRetryService2.testSimpleUpdate(5651L);
System.out.println(s); System.out.println(s);
} catch (Exception e) { } catch (Exception e) {
log.error("", e); log.error("", e);
@ -86,7 +86,7 @@ public class ExistsTransactionalRetryServiceTest {
.thenReturn(new Result(0, "2")) .thenReturn(new Result(0, "2"))
.thenReturn(new Result(0, "3")) .thenReturn(new Result(0, "3"))
.thenReturn(new Result(0, "4")) .thenReturn(new Result(0, "4"))
.thenReturn(new Result(0, "5")) .thenReturn(new Result(5, "5"))
; ;
try { try {
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {

View File

@ -30,7 +30,7 @@ public class NestMethodServiceTest {
.thenReturn(new Result(0, "2")) .thenReturn(new Result(0, "2"))
.thenReturn(new Result(0, "3")) .thenReturn(new Result(0, "3"))
.thenReturn(new Result(0, "4")) .thenReturn(new Result(0, "4"))
.thenReturn(new Result(0, "5")) .thenReturn(new Result(1, "5"))
; ;
try { try {
nestMethodService.testNestMethod(); nestMethodService.testNestMethod();