当前位置: 首页 > news >正文

spring aop实现接口超时处理组件

文章目录

    • 实现思路
    • 实现代码
    • starter组件

实现思路

  1. 这里使用FutureTask,它通过get方法以阻塞的方式获取执行结果,并设定超时时间:
public V get() throws InterruptedException, ExecutionException ;public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException ;
  1. 利用spring aop解耦业务
  2. 定义业务异常信息

实现代码

定义注解:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
public @interface TimeoutCheck {/*** 超时时间,默认5秒*/long timeout() default 5L;/*** 超时单位,默认秒*/TimeUnit unit() default TimeUnit.SECONDS;/*** 超时后是否销毁线程*/boolean destroy() default true;
}

这里有一个destroy()的方法,因为我们在执行时开独立线程处理,所以这个方法是为了在超时后,用来判断是否销毁还在执行的线程;

定义异常:

注意:这里的父类应该是项目中的基础业务异常类;

public class TimeoutCheckException extends RuntimeException{public TimeoutCheckException(String message) {super(message);}public TimeoutCheckException(String message, Throwable throwable) {super(message, throwable);}
}

再顺便定义一个属性配置:

这个的作用是全局控制开关,当不需要的时候可以直接通过配置关闭;

@Component
@ConfigurationProperties(prefix = "aliweb.timeout")
public class TimeoutCheckProperties {private boolean enable = true;public boolean isEnable() {return enable;}public void setEnable(boolean enable) {this.enable = enable;}
}

最后就是我们的aop类:

@Aspect
@Component
public class TimeoutAop {private static final Logger logger = LoggerFactory.getLogger(TimeoutAop.class);@Autowiredprivate TimeoutCheckProperties timeoutCheckProperties;@Pointcut("@annotation(timeoutCheck)")public void pointCut(TimeoutCheck timeoutCheck) {}@Around(value = "pointCut(timeoutCheck)", argNames = "joinPoint, timeoutCheck")public Object around(ProceedingJoinPoint joinPoint, TimeoutCheck timeoutCheck) throws Throwable {if (!timeoutCheckProperties.isEnable()) {return joinPoint.proceed();}long timeout = timeoutCheck.timeout();if (timeout <= 0) {throw new TimeoutCheckException("业务逻辑执行时间不能小于等于0");}long start = System.currentTimeMillis();String msg = null;Exception error = null;Object data = null;FutureTask<Object> futureTask = createTask(joinPoint);try {Thread thread = new Thread(futureTask);thread.start();data = futureTask.get(timeout, timeoutCheck.unit());} catch (InterruptedException e) {msg = "执行中断";error = e;} catch (ExecutionException e) {msg = "执行异常";error = e;} catch (TimeoutException e) {msg = "执行超时";error = e;} finally {futureTask.cancel(timeoutCheck.destroy());}logger.debug("执行时间:{}", System.currentTimeMillis() - start);if (error != null) {String suf = error.getMessage() == null ? "" : ":" + error.getMessage();logger.error(msg + suf, error);throw new TimeoutCheckException(msg + suf, error);}return data;}private static FutureTask<Object> createTask(ProceedingJoinPoint joinPoint) {return new FutureTask<>(() -> {try {return joinPoint.proceed();} catch (Throwable e) {throw new RuntimeException(e);}});}}

starter组件

将功能提取成starter组件:

  1. 定义配置类
@Configuration
@ComponentScan("com.liry.aliweb.timeout")
public class TimeoutCheckAutoConfig {
}
  1. 定义配置扫描文件spring.factories,路径:

    src/main/resources/META-INF/spring.factories

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.liry.aliweb.timeout.config.TimeoutCheckAutoConfig
    
  2. pom增加依赖:

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId>
    </dependency>
    

如上,在主项目引入时就可以直接使用了

http://www.lryc.cn/news/296400.html

相关文章:

  • c++设计模式之装饰器模式
  • WordPress如何实现随机显示一句话经典语录?怎么添加到评论框中?
  • 【退役之重学前端】vite, vue3, vue-router, vuex, ES6学习日记
  • [linux]-总线,设备,驱动,dts
  • python3实现gitlab备份文件上传腾讯云COS
  • 292.Nim游戏
  • Spring和Spring Boot的区别
  • 备战蓝桥杯---动态规划(理论基础)
  • FPGA_ip_pll
  • 【实验3】统计某电商网站买家收藏商品数量
  • 【Qt】Android上运行keeps stopping, Desktop上正常
  • 算法学习打卡day47|单调栈系列题目
  • Maven构建OSGI+HttpServer应用
  • chrome扩展插件常用文件及作用
  • PdfFactory Pro软件下载以及序列号注册码生成器
  • jsp康养小镇管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
  • Android 无操作之后定时退出
  • CMS 检测神器:CMSeek 保姆级教程(附链接)
  • oracle 启动命令以及ORA-01033问题处理、删除归档日志
  • 【大模型上下文长度扩展】MedGPT:解决遗忘 + 永久记忆 + 无限上下文
  • 谷歌seo搜索引擎优化有什么思路?
  • 腾讯云与IBM共同打造“高性能计算服务解决方案“
  • 【SparkML实践7】特征选择器FeatureSelector
  • LeetCode983. Minimum Cost For Tickets——动态规划
  • 百卓Smart管理平台 uploadfile.php 文件上传漏洞【CVE-2024-0939】
  • 项目中常用的一些数据库及缓存
  • MoE-LLaVA:具有高效缩放和多模态专业知识的大型视觉语言模型
  • 【Java】ArrayList和LinkedList的区别是什么
  • RabbitMQ-4.MQ的可靠性
  • 编程相关的经典的网站和书籍