最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Retry 重試實(shí)例詳解

 更新時(shí)間:2022年10月28日 17:08:33   作者:廢物大師兄  
這篇文章主要介紹了Spring Retry 重試,使用方式有兩種分別是命令式和聲明式,本文通過實(shí)例代碼給大家詳細(xì)講解,需要的朋友可以參考下

spring-retry是什么?

spring-retry是spring提供的一個重試框架,原本自己實(shí)現(xiàn)的重試機(jī)制,現(xiàn)在spring幫封裝好提供更加好的編碼體驗(yàn)。

重試的使用場景比較多,比如調(diào)用遠(yuǎn)程服務(wù)時(shí),由于網(wǎng)絡(luò)或者服務(wù)端響應(yīng)慢導(dǎo)致調(diào)用超時(shí),此時(shí)可以多重試幾次。用定時(shí)任務(wù)也可以實(shí)現(xiàn)重試的效果,但比較麻煩,用Spring Retry的話一個注解搞定所有。話不多說,先看演示。

首先引入依賴

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.3.4</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.9.1</version>
</dependency>

使用方式有兩種:命令式和聲明式

命令式

/**
 * 命令式的方式使用Spring Retry
 */
@GetMapping("/hello")
public String hello(@RequestParam("code") Integer code) throws Throwable {
    RetryTemplate retryTemplate = RetryTemplate.builder()
            .maxAttempts(3)
            .fixedBackoff(1000)
            .retryOn(RemoteAccessException.class)
            .build();
    retryTemplate.registerListener(new MyRetryListener());

    String resp = retryTemplate.execute(new RetryCallback<String, Throwable>() {
        @Override
        public String doWithRetry(RetryContext context) throws Throwable {
            return helloService.hello(code);
        }
    });

    return resp;
}

定義一個RetryTemplate,然后調(diào)用execute方法,可配置項(xiàng)比較多,不一一列舉

真正使用的時(shí)候RetryTemplate可以定義成一個Bean,例如:

@Configuration
public class RetryConfig {
    @Bean
    public RetryTemplate retryTemplate() {
        RetryTemplate retryTemplate = RetryTemplate.builder()
                .maxAttempts(3)
                .fixedBackoff(1000)
                .withListener(new MyRetryListener())
                .retryOn(RemoteAccessException.class)
                .build();
        return retryTemplate;
    }
}

業(yè)務(wù)代碼:

/**
 * 命令式的方式使用Spring Retry
 */
@Override
public String hello(int code) {
    if (0 == code) {
        System.out.println("出錯了");
        throw new RemoteAccessException("出錯了");
    }
    System.out.println("處理完成");
    return "ok";
}

監(jiān)聽器實(shí)現(xiàn):

package com.example.retry.listener;

import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.RetryListener;

public class MyRetryListener implements RetryListener {
    @Override
    public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
        System.out.println("open");
        return true;
    }

    @Override
    public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        System.out.println("close");
    }

    @Override
    public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        System.out.println("error");
    }
}

聲明式(注解方式)

/**
 * 注解的方式使用Spring Retry
 */
@Retryable(value = Exception.class, maxAttempts = 2, backoff = @Backoff(value = 1000, delay = 2000, multiplier = 0.5))
@Override
public String hi(int code) {
    System.out.println("方法被調(diào)用");
    int a = 1/code;
    return "ok";
}

@Recover
public String hiRecover(Exception ex, int code) {
    System.out.println("重試結(jié)束");
    return "asdf";
}

這里需要主要的幾點(diǎn)

  • @EnableRetry(proxyTargetClass = true/false)
  • @Retryable 修飾的方法必須是public的,而且不能是同一個類中調(diào)用
  • @Recover 修飾的方法簽名必須與@Retryable修飾的方法一樣,除了第一個參數(shù)外
/**
 * 注解的方式使用Spring Retry
 */
@GetMapping("/hi")
public String hi(@RequestParam("code") Integer code) {
    return helloService.hi(code);
}

1. 用法

聲明式

@Configuration
@EnableRetry
public class Application {

}
@Service
class Service {
    @Retryable(RemoteAccessException.class)
    public void service() {
        // ... do something
    }
    @Recover
    public void recover(RemoteAccessException e) {
       // ... panic
    }
}

命令式

RetryTemplate template = RetryTemplate.builder()
				.maxAttempts(3)
				.fixedBackoff(1000)
				.retryOn(RemoteAccessException.class)
				.build();

template.execute(ctx -> {
    // ... do something
});

2. RetryTemplate

為了自動重試,Spring Retry 提供了 RetryOperations 重試操作策略

public interface RetryOperations {

    <T> T execute(RetryCallback<T> retryCallback) throws Exception;

    <T> T execute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback)
        throws Exception;

    <T> T execute(RetryCallback<T> retryCallback, RetryState retryState)
        throws Exception, ExhaustedRetryException;

    <T> T execute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback,
        RetryState retryState) throws Exception;

}

基本回調(diào)是一個簡單的接口,允許插入一些要重試的業(yè)務(wù)邏輯:

public interface RetryCallback<T> {

    T doWithRetry(RetryContext context) throws Throwable;
}

回調(diào)函數(shù)被嘗試,如果失?。ㄍㄟ^拋出異常),它將被重試,直到成功或?qū)崿F(xiàn)決定中止。

RetryOperations最簡單的通用實(shí)現(xiàn)是RetryTemplate

RetryTemplate template = new RetryTemplate();

TimeoutRetryPolicy policy = new TimeoutRetryPolicy();
policy.setTimeout(30000L);

template.setRetryPolicy(policy);

Foo result = template.execute(new RetryCallback<Foo>() {

    public Foo doWithRetry(RetryContext context) {
        // Do stuff that might fail, e.g. webservice operation
        return result;
    }

});

從Spring Retry 1.3開始,RetryTemplate支持流式配置:

RetryTemplate.builder()
      .maxAttempts(10)
      .exponentialBackoff(100, 2, 10000)
      .retryOn(IOException.class)
      .traversingCauses()
      .build();

RetryTemplate.builder()
      .fixedBackoff(10)
      .withinMillis(3000)
      .build();

RetryTemplate.builder()
      .infiniteRetry()
      .retryOn(IOException.class)
      .uniformRandomBackoff(1000, 3000)
      .build();

3. RecoveryCallback

當(dāng)重試耗盡時(shí),RetryOperations可以將控制傳遞給不同的回調(diào):RecoveryCallback。

Foo foo = template.execute(new RetryCallback<Foo>() {
    public Foo doWithRetry(RetryContext context) {
        // business logic here
    },
  new RecoveryCallback<Foo>() {
    Foo recover(RetryContext context) throws Exception {
          // recover logic here
    }
});

4. Listeners

public interface RetryListener {

    void open(RetryContext context, RetryCallback<T> callback);

    void onSuccess(RetryContext context, T result);

    void onError(RetryContext context, RetryCallback<T> callback, Throwable e);

    void close(RetryContext context, RetryCallback<T> callback, Throwable e);
}

在最簡單的情況下,open和close回調(diào)在整個重試之前和之后,onSuccess和onError應(yīng)用于個別的RetryCallback調(diào)用,onSuccess方法在成功調(diào)用回調(diào)之后被調(diào)用。

5. 聲明式重試

有時(shí),你希望在每次業(yè)務(wù)處理發(fā)生時(shí)都重試一些業(yè)務(wù)處理。這方面的典型例子是遠(yuǎn)程服務(wù)調(diào)用。Spring Retry提供了一個AOP攔截器,它將方法調(diào)用封裝在RetryOperations實(shí)例中。RetryOperationsInterceptor執(zhí)行被攔截的方法,并根據(jù)提供的RepeatTemplate中的RetryPolicy在失敗時(shí)重試。

你可以在 @Configuration 類上添加一個 @EnableRetry 注解,并且在你想要進(jìn)行重試的方法(或者類)上添加 @Retryable 注解,還可以指定任意數(shù)量的重試監(jiān)聽器。

@Configuration
@EnableRetry
public class Application {

    @Bean
    public Service service() {
        return new Service();
    }

    @Bean public RetryListener retryListener1() {
        return new RetryListener() {...}
    }

    @Bean public RetryListener retryListener2() {
        return new RetryListener() {...}
    }

}

@Service
class Service {
    @Retryable(RemoteAccessException.class)
    public service() {
        // ... do something
    }
}

可以使用 @Retryable 的屬性類控制 RetryPolicy 和 BackoffPolicy

@Service
class Service {
    @Retryable(maxAttempts=12, backoff=@Backoff(delay=100, maxDelay=500))
    public service() {
        // ... do something
    }
}

如果希望在重試用盡時(shí)采用替代代碼返回,則可以提供恢復(fù)方法。方法應(yīng)該聲明在與@Retryable實(shí)例相同的類中,并標(biāo)記為@Recover。返回類型必須匹配@Retryable方法?;謴?fù)方法的參數(shù)可以包括拋出的異常和(可選地)傳遞給原始可重試方法的參數(shù)(或者它們的部分列表,只要在需要的最后一個之前不省略任何參數(shù))。

@Service
class Service {
    @Retryable(RemoteAccessException.class)
    public void service(String str1, String str2) {
        // ... do something
    }
    @Recover
    public void recover(RemoteAccessException e, String str1, String str2) {
       // ... error handling making use of original args if required
    }
}

若要解決可選擇用于恢復(fù)的多個方法之間的沖突,可以顯式指定恢復(fù)方法名稱。

@Service
class Service {
    @Retryable(recover = "service1Recover", value = RemoteAccessException.class)
    public void service1(String str1, String str2) {
        // ... do something
    }

    @Retryable(recover = "service2Recover", value = RemoteAccessException.class)
    public void service2(String str1, String str2) {
        // ... do something
    }

    @Recover
    public void service1Recover(RemoteAccessException e, String str1, String str2) {
        // ... error handling making use of original args if required
    }

    @Recover
    public void service2Recover(RemoteAccessException e, String str1, String str2) {
        // ... error handling making use of original args if required
    }
}

https://github.com/spring-projects/spring-retry

到此這篇關(guān)于Spring Retry 重試的文章就介紹到這了,更多相關(guān)Spring Retry 重試內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring的TransactionSynchronizationAdapter事務(wù)源碼解析

    spring的TransactionSynchronizationAdapter事務(wù)源碼解析

    這篇文章主要介紹了spring的TransactionSynchronizationAdapter事務(wù)源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • 詳解springboot整合ehcache實(shí)現(xiàn)緩存機(jī)制

    詳解springboot整合ehcache實(shí)現(xiàn)緩存機(jī)制

    這篇文章主要介紹了詳解springboot整合ehcache實(shí)現(xiàn)緩存機(jī)制,ehcache提供了多種緩存策略,主要分為內(nèi)存和磁盤兩級,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • springboot返回值轉(zhuǎn)成JSONString的處理方式

    springboot返回值轉(zhuǎn)成JSONString的處理方式

    這篇文章主要介紹了springboot返回值轉(zhuǎn)成JSONString的處理方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • springboot實(shí)現(xiàn)將自定義日志格式存儲到mongodb中

    springboot實(shí)現(xiàn)將自定義日志格式存儲到mongodb中

    這篇文章主要介紹了springboot實(shí)現(xiàn)將自定義日志格式存儲到mongodb中的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • springboot 在xml里讀取yml的配置信息的示例代碼

    springboot 在xml里讀取yml的配置信息的示例代碼

    這篇文章主要介紹了springboot 在xml里讀取yml的配置信息的示例代碼,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • springboot 排除redis的自動配置操作

    springboot 排除redis的自動配置操作

    這篇文章主要介紹了springboot 排除redis的自動配置操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 詳解Struts2中配置默認(rèn)Action的方法

    詳解Struts2中配置默認(rèn)Action的方法

    本篇文章主要介紹了詳解Struts2中配置默認(rèn)Action的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • SpringBoot自定義注解及AOP的開發(fā)和使用詳解

    SpringBoot自定義注解及AOP的開發(fā)和使用詳解

    在公司項(xiàng)目中,如果需要做一些公共的功能,如日志等,最好的方式是使用自定義注解,自定義注解可以實(shí)現(xiàn)我們對想要添加日志的方法上添加,這篇文章基于日志功能來講講自定義注解應(yīng)該如何開發(fā)和使用,需要的朋友可以參考下
    2023-08-08
  • Spring多線程通過@Scheduled實(shí)現(xiàn)定時(shí)任務(wù)

    Spring多線程通過@Scheduled實(shí)現(xiàn)定時(shí)任務(wù)

    這篇文章主要介紹了Spring多線程通過@Scheduled實(shí)現(xiàn)定時(shí)任務(wù),@Scheduled?定時(shí)任務(wù)調(diào)度注解,是spring定時(shí)任務(wù)中最重要的,下文關(guān)于其具體介紹,需要的小伙伴可以參考一下
    2022-05-05
  • 利用EasyPOI實(shí)現(xiàn)多sheet和列數(shù)的動態(tài)生成

    利用EasyPOI實(shí)現(xiàn)多sheet和列數(shù)的動態(tài)生成

    EasyPoi功能如同名字,主打的功能就是容易,讓一個沒見接觸過poi的人員就可以方便的寫出Excel導(dǎo)出,Excel導(dǎo)入等功能,本文主要來講講如何利用EasyPOI實(shí)現(xiàn)多sheet和列數(shù)的動態(tài)生成,需要的可以了解下
    2025-03-03

最新評論

札达县| 绍兴市| 沙坪坝区| 克东县| 南木林县| 泉州市| 买车| 阿拉善盟| 六盘水市| 望奎县| 新乐市| 湘潭市| 凉城县| 通辽市| 威海市| 德江县| 霍城县| 广宗县| 广南县| 财经| 南丰县| 东兴市| 广饶县| 宝山区| 依兰县| 安国市| 庆城县| 三江| 宜兰市| 格尔木市| 法库县| 清徐县| 宾川县| 东乌珠穆沁旗| 龙门县| 崇州市| 蓬溪县| 木里| 余庆县| 威信县| 横山县|