spring 项目集成配置_Spring重试–与项目集成的方式

spring 项目集成配置

如果您需要在代码中实现健壮的重试逻辑,一种行之有效的方法是使用spring重试库。 我的目的不是要展示如何使用spring retry项目本身,而是要演示将其集成到代码库中的不同方式。

考虑一种服务来调用外部系统:

package retry.service;public interface RemoteCallService {String call() throws Exception;
}

假设此调用可能失败,并且您希望每次调用失败都可以重试三次该调用,每次延迟2秒,所以为了模拟此行为,我已经使用Mockito定义了模拟服务,请注意,此返回为嘲笑的Spring bean:

@Bean
public RemoteCallService remoteCallService() throws Exception {RemoteCallService remoteService = mock(RemoteCallService.class);when(remoteService.call()).thenThrow(new RuntimeException("Remote Exception 1")).thenThrow(new RuntimeException("Remote Exception 2")).thenReturn("Completed");return remoteService;
}

因此,该模拟服务本质上将失败2次,并在第三个调用成功。

这是对重试逻辑的测试:

public class SpringRetryTests {@Autowiredprivate RemoteCallService remoteCallService;@Testpublic void testRetry() throws Exception {String message = this.remoteCallService.call();verify(remoteCallService, times(3)).call();assertThat(message, is("Completed"));}
}

我们确保该服务被调用3次,以解决前两个失败的呼叫以及成功的第三个呼叫。

如果我们在调用此服务时直接合并spring-retry,那么代码将如下所示:

@Test
public void testRetry() throws Exception {String message = this.retryTemplate.execute(context -> this.remoteCallService.call());verify(remoteCallService, times(3)).call();assertThat(message, is("Completed"));
}

但是,这不是理想的选择,更好的包含方法是调用者不必明确知道存在重试逻辑的事实。

鉴于此,以下是合并Spring重试逻辑的方法。

方法1:自定义方面合并Spring重试

这种方法应该相当直观,因为可以将重试逻辑视为跨领域关注点,并且使用Aspects是实现跨领域关注点的好方法。 包含Spring重试的一个方面将遵循以下原则:

package retry.aspect;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.support.RetryTemplate;@Aspect
public class RetryAspect {private static Logger logger = LoggerFactory.getLogger(RetryAspect.class);@Autowiredprivate RetryTemplate retryTemplate;@Pointcut("execution(* retry.service..*(..))")public void serviceMethods() {//}@Around("serviceMethods()")public Object aroundServiceMethods(ProceedingJoinPoint joinPoint) {try {return retryTemplate.execute(retryContext -> joinPoint.proceed());} catch (Throwable e) {throw new RuntimeException(e);}}
}

这方面拦截了远程服务调用,并将该调用委托给retryTemplate。 完整的工作测试在这里 。

方法2:使用Spring-retry提供的建议

Spring-retry项目提供了开箱即用的建议,可确保确保可以重试目标服务。 AOP配置用于围绕服务编织建议,这需要处理原始xml,这与以前的方法不同,前一种方法可以使用Spring Java配置来编织方面。 xml配置如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><aop:config><aop:pointcut id="transactional"expression="execution(* retry.service..*(..))" /><aop:advisor pointcut-ref="transactional"advice-ref="retryAdvice" order="-1"/></aop:config></beans>

完整的工作测试在这里 。

方法3:声明式重试逻辑

这是推荐的方法,您将看到代码比前两种方法更加简洁。 使用这种方法,唯一需要做的就是声明性地指出哪些方法需要重试:

package retry.service;import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;public interface RemoteCallService {@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 2000))String call() throws Exception;
}

以及使用此声明性重试逻辑的完整测试,也可以在这里找到 :

package retry;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import retry.service.RemoteCallService;import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.*;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class SpringRetryDeclarativeTests {@Autowiredprivate RemoteCallService remoteCallService;@Testpublic void testRetry() throws Exception {String message = this.remoteCallService.call();verify(remoteCallService, times(3)).call();assertThat(message, is("Completed"));}@Configuration@EnableRetrypublic static class SpringConfig {@Beanpublic RemoteCallService remoteCallService() throws Exception {RemoteCallService remoteService = mock(RemoteCallService.class);when(remoteService.call()).thenThrow(new RuntimeException("Remote Exception 1")).thenThrow(new RuntimeException("Remote Exception 2")).thenReturn("Completed");return remoteService;}}
}

@EnableRetry批注激活@Retryable批注方法的处理,并在内部使用方法2的逻辑,而最终用户无需对其进行明确说明。

我希望这会使您对如何将Spring-retry纳入项目有更好的了解。 我在这里演示的所有代码也可以在我的github项目中找到 :https://github.com/bijukunjummen/test-spring-retry

翻译自: https://www.javacodegeeks.com/2014/12/spring-retry-ways-to-integrate-with-your-project.html

spring 项目集成配置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/338653.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis 内存不足 排查_排查redis占用内存达90%以上

帮别人排查一个问题,项目还没上线但redis占用内存很高。思路如下&#xff1a;1、登陆redis控制台&#xff0c;首先用 keys * 获取所有的key> keys *x:x:ax:x:bx:x:c发现key也就十来个&#xff0c;用 TYPE x:x:a 发现a是一个list数据类型用lrange命令查看list中指定索引的值用…

C或C 如何通过程序执行shell命令并获取命令执行结果?

1 应用场景最近在实际程序开发中&#xff0c;需要通过程序执行 shell 命令&#xff0c;并获取命令输出内容。但是系统自带的 system 只能返回命令执行成功与否&#xff0c;不能捕获命令输出。2 扩展性由于应用场景本就广泛&#xff0c;因此扩展性较好。此函数可以执行任意命令&…

linux centos7安装ngix,centos7 环境下安装nginx--Linux

本文将要为您介绍的是centos7 环境下安装nginx--Linux,具体完成步骤:一、安装前需要的编译环境准备1、安装makeyum install -y gcc automake autoconf libtool make2、安装gcc、gcc-cyum install -y gcc gcc-c3、关闭防火墙iptables -F4、关闭selinux#临时关闭&#xff1a;sete…

16进制数组转成10进制 qt_QT 十六进制字符串转化为十六进制编码

/*************************************************Function: hexStringtoByteArray()Description:十六进制字串转化为十六进制编码Calls: formatString()Called By:Input: hex->待转化的十六进制字串Output: NULLReturn: QByteArrayOthers: NULL************************…

primefaces_使用PrimeFaces开发数据导出实用程序

primefaces我的日常工作涉及大量使用数据。 我们使用关系数据库来存储所有内容&#xff0c;因为我们依赖于企业级的数据管理。 有时&#xff0c;具有将数据提取为简单格式&#xff08;例如电子表格&#xff09;的功能很有用&#xff0c;以便我们可以按需进行操作。 这篇文章概述…

如何优雅地实现判断一个值是否在一个集合中?

如何判断某变量是否在某个集合中&#xff1f;注意&#xff0c;这里的集合可能并不是指确定的常量&#xff0c;也可能是变量。版本0#include int main(){int a 5;if(a 1 || a 2 || a 3 || a 4 || a 5){std::cout<<"find it"<<std::endl;}return 0;…

c语言所有关键字作用,void_C语言void关键字详解

void类型修饰符(type specifier)表示“没有值可以获得”。因此&#xff0c;不可以采用这个类型声明变量或常量。void 类型可以用于下面各小节所描述的目的。void用于函数声明没有返回值的函数&#xff0c;其类型为 void。例如&#xff0c;标准库函数 perror() 被声明为以下原型…

jvmti_拥有您的堆:使用JVMTI迭代类实例

jvmti今天&#xff0c;我想谈一谈我们大多数人每天都不会看到和使用的另一种Java&#xff0c;更确切地说&#xff0c;是有关较低级别的绑定&#xff0c;一些本机代码以及如何执行一些小的魔术。 尽管我们不会在JVM上找到真正的魔力源&#xff0c;但是在单个帖子的范围内可以实现…

babylonjs 分部加载模型_BabylonJS加载OBJ或STL模型文件实例

JavaScript语言&#xff1a;JaveScriptBabelCoffeeScript确定var canvas document.getElementById("renderCanvas");var engine new BABYLON.Engine(canvas, true);var createScene function() {// This creates a basic Babylon Scene object (non-mesh)var scen…

骚操作:利用强弱符号制作插件库

当有强符号和弱符号时&#xff0c;选择使用强符号那么我们正可以利用这个原则做以下事情&#xff1a;定义为弱符号&#xff0c;如果是弱符号&#xff0c;使用默认行为如果链接了库&#xff0c;是强符号&#xff0c;则使用外部定义行为以此来实现一个类似插件的功能。通俗一点说…

c语言里 t是什么作用,c语言里的\t是什么意思

c语言里的&#xff3c;t是什么意思以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;c语言里的&#xff3c;t是什么意思正宗叫法是“水平制表符”&#xff0c;就是在输出媒体上水平跳过多个空格…

boot jersey_Jersey和Spring Boot入门

boot jersey除了许多新功能&#xff0c;Spring Boot 1.2还带来了Jersey支持。 这是吸引喜欢标准方法的开发人员的重要一步&#xff0c;因为他们现在可以使用JAX-RS规范构建RESTful API&#xff0c;并将其轻松部署到Tomcat或任何其他Springs Boot支持的容器中。 带有Spring平台的…

mime类型是什么 node_Node.js - 文件系统获取文件类型

我需要借助node.js来获取文件的文件类型以设置内容类型。我知道我可以很容易地检查文件扩展名&#xff0c;但我也有没有扩展名的文件&#xff0c;其内容类型应该是image/png,text/html aso。Node.js - 文件系统获取文件类型这是我的代码(我知道这并没有太大的意义&#xff0c;但…

函数或全局变量重复定义时会怎样?

可能有些朋友第一反应是&#xff0c;那肯定是编译不过喽&#xff1a;// fun.c #include void func() {printf("编程珠玑\n"); }// main.c #include void func() {printf("公众号\n"); } int main(void) {func();return 0; }编译&#xff1a;$ gcc -o main …

c语言开源编辑器,一个C语言编写的跨平台C语言编译器(开源) UCC

很多科班出身的搞开发的同事大都应该学过《编译原理》这门课程&#xff0c;或许也动手做过一些实践。这次向大家推荐一个由清华大学学生完成的C语言编译器实现 -- UCC。这个项目目前位于sf.net网站&#xff0c;开放源代码&#xff0c;代码使用C语言编写&#xff0c;对于理解和实…

java持久性与安全性_Java持久性锁定初学者指南

java持久性与安全性隐式锁定 在并发理论中&#xff0c;锁定用于保护可变共享数据免受危险数据完整性异常的影响。 因为锁管理是一个非常复杂的问题&#xff0c;所以大多数应用程序都依赖于其数据提供程序隐式锁技术。 将整个锁定职责委托给数据库系统既可以简化应用程序开发&a…

c语言实验报告5数组,c语言实验报告五一维数组.doc

c语言实验报告五一维数组《C程序设计》课程实验报告学院&#xff1a; 班级&#xff1a; 姓名&#xff1a; 学号&#xff1a; 实验设备&#xff1a;计算机1台2011年3月1日实验项目名称一维数组掌握一维数组的定义、初始化&#xff0c;以及一维数组元素的下标法引用。实验要求&am…

当C语言函数执行成功时,返回1和返回0究竟哪个好?

基本上&#xff0c;没有人会将大段的C语言代码全部塞入 main() 函数。更好的做法是按照复用率高&#xff0c;耦合性低的原则&#xff0c;尽可能的将代码拆分不同的功能模块&#xff0c;并封装成函数。C语言代码的组合千变万化&#xff0c;因此函数的功能可能会比较复杂&#xf…

ubuntu自定义安装里怎么选_超市里的五香粉怎么选?看懂配料表,两个小技巧,不怕选不好。...

点击右上角【关注】&#xff0c;可获得本头条号推荐的更多美食干货五香粉是家庭常用的一种调味料&#xff0c;焖、炖、烧、煮、卤都常备使用&#xff0c;如今市场上的五香粉品牌也是相当繁多&#xff0c;质量也是参差不齐&#xff0c;有时买到的五香粉烧制的菜肴根本就不好吃&a…

原来C语言还可以这样实现“泛型编程”!

在回答标题问题之前&#xff0c;先了解下什么是泛型编程。泛型编程&#xff08;generic programming&#xff09;是程序设计语言的一种风格或范式。泛型允许程序员在强类型程序设计语言中编写代码时使用一些以后才指定的类型&#xff0c;在实例化时作为参数指明这些类型。C支持…