日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

spring aop不执行_使用Spring AOP重试方法执行

發布時間:2023/12/3 javascript 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spring aop不执行_使用Spring AOP重试方法执行 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

spring aop不執行

我的一位博客關注者發送了一封電子郵件,要求我顯示“ Spring AOP的RealWorld用法”示例。 他提到,在大多數示例中,都演示了Spring AOP日志記錄方法進入/退出事務管理安全性檢查中的用法。

他想知道Spring AOP在“針對實際問題的真實項目”中的用法。 因此,我想展示如何在我的一個項目中使用Spring AOP來處理一個實際問題。

我們不會在開發階段遇到任何問題,只有在負載測試期間或僅在生產環境中才知道。

例如:

  • 由于網絡延遲問題而導致的遠程WebService調用失敗
  • 由于Lock異常等導致數據庫查詢失敗

在大多數情況下,只需重試同一操作就足以解決此類故障。

讓我們看看如果發生任何異常,如何使用Spring AOP自動重試方法執行。 我們可以使用Spring AOP @Around建議為那些需要重試其方法的對象創建代理,并在Aspect中實現重試邏輯。

在繼續執行這些Spring Advice和Aspect之前,首先讓我們編寫一個簡單的實用程序來執行“任務” ,該任務將自動重試N次,而忽略給定的異常集。

public interface Task<T> {T execute(); }import java.util.HashSet; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory;public class TaskExecutionUtil {private static Logger logger = LoggerFactory.getLogger(TaskExecutionUtil.class);@SafeVarargspublic static <T> T execute(Task<T> task, int noOfRetryAttempts, long sleepInterval, Class<? extends Throwable>... ignoreExceptions) {if (noOfRetryAttempts < 1) {noOfRetryAttempts = 1;}Set<Class<? extends Throwable>> ignoreExceptionsSet = new HashSet<Class<? extends Throwable>>();if (ignoreExceptions != null && ignoreExceptions.length > 0) {for (Class<? extends Throwable> ignoreException : ignoreExceptions) {ignoreExceptionsSet.add(ignoreException);}}logger.debug("noOfRetryAttempts = "+noOfRetryAttempts);logger.debug("ignoreExceptionsSet = "+ignoreExceptionsSet);T result = null;for (int retryCount = 1; retryCount <= noOfRetryAttempts; retryCount++) {logger.debug("Executing the task. Attemp#"+retryCount);try {result = task.execute();break;} catch (RuntimeException t) {Throwable e = t.getCause();logger.error(" Caught Exception class"+e.getClass());for (Class<? extends Throwable> ignoreExceptionClazz : ignoreExceptionsSet) {logger.error(" Comparing with Ignorable Exception : "+ignoreExceptionClazz.getName());if (!ignoreExceptionClazz.isAssignableFrom(e.getClass())) {logger.error("Encountered exception which is not ignorable: "+e.getClass());logger.error("Throwing exception to the caller");throw t;}}logger.error("Failed at Retry attempt :" + retryCount + " of : " + noOfRetryAttempts);if (retryCount >= noOfRetryAttempts) {logger.error("Maximum retrial attempts exceeded.");logger.error("Throwing exception to the caller");throw t;}try {Thread.sleep(sleepInterval);} catch (InterruptedException e1) {//Intentionally left blank}}}return result;}}

我希望這種方法可以自我解釋。 它要花費一個Task 并重noOfRetryAttempts次,以防task.execute()方法拋出任何Exception且ignoreExceptions指示重試時要忽略的異常類型。

現在讓我們創建一個Retry注釋,如下所示:

import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Retry {public int retryAttempts() default 3;public long sleepInterval() default 1000L; //millisecondsClass<? extends Throwable>[] ignoreExceptions() default { RuntimeException.class };}

我們將使用此@Retry批注來劃分需要重試的方法。

現在讓我們實現適用于帶有@Retry批注的方法的Aspect。

import java.lang.reflect.Method;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.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component;@Component @Aspect public class MethodRetryHandlerAspect {private static Logger logger = LoggerFactory.getLogger(MethodRetryHandlerAspect.class);@Around("@annotation(com.sivalabs.springretrydemo.Retry)")public Object audit(ProceedingJoinPoint pjp) {Object result = null;result = retryableExecute(pjp);return result;}protected Object retryableExecute(final ProceedingJoinPoint pjp){MethodSignature signature = (MethodSignature) pjp.getSignature();Method method = signature.getMethod();logger.debug("-----Retry Aspect---------");logger.debug("Method: "+signature.toString());Retry retry = method.getDeclaredAnnotation(Retry.class);int retryAttempts = retry.retryAttempts();long sleepInterval = retry.sleepInterval();Class<? extends Throwable>[] ignoreExceptions = retry.ignoreExceptions();Task<Object> task = new Task<Object>() {@Overridepublic Object execute() {try {return pjp.proceed();} catch (Throwable e) {throw new RuntimeException(e);}}};return TaskExecutionUtil.execute(task, retryAttempts, sleepInterval, ignoreExceptions);} }

而已。 我們只需要一些測試用例即可對其進行實際測試。

首先創建AppConfig.java配置類,如下所示:

import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration @ComponentScan @EnableAspectJAutoProxy public class AppConfig {}

和幾個虛擬Service Bean。

import org.springframework.stereotype.Service;@Service public class ServiceA {private int counter = 1;public void method1() {System.err.println("----method1----");}@Retry(retryAttempts=5, ignoreExceptions={NullPointerException.class})public void method2() {System.err.println("----method2 begin----");if(counter != 3){counter++;throw new NullPointerException();}System.err.println("----method2 end----"); } }import java.io.IOException; import org.springframework.stereotype.Service;@Service public class ServiceB {@Retry(retryAttempts = 2, ignoreExceptions={IOException.class})public void method3() {System.err.println("----method3----");if(1 == 1){throw new ArrayIndexOutOfBoundsException();}}@Retrypublic void method4() {System.err.println("----method4----");} }

最后編寫一個簡單的Junit測試來調用這些方法。

import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=AppConfig.class) public class RetryTest {@Autowired ServiceA svcA;@Autowired ServiceB svcB;@Testpublic void testA(){svcA.method1();}@Testpublic void testB(){svcA.method2();}@Test(expected=RuntimeException.class)public void testC(){svcB.method3();}@Testpublic void testD(){svcB.method4();} }

是的,我知道我可以寫出更好的這些測試方法,但我希望您能理解。

運行JUnit測試并觀察log語句以驗證是否在發生Exception的情況下重試方法。

  • 情況1:調用ServiceA.method1()時,根本不會應用MethodRetryHandlerAspect。
  • 情況2:調用ServiceA.method2()時,我們將維護一個計數器并拋出NullPointerException 2次。 但是我們已經標記了該方法以忽略NullPointerExceptions。 因此它將繼續重試5次。 但是第三次??方法將正常執行并正常退出該方法。
  • 情況3:調用ServiceB.method3()時,我們將拋出ArrayIndexOutOfBoundsException,但該方法被標記為僅忽略IOException。 因此,將不會重試此方法的執行,并且會立即引發Exception。
  • 情況4:調用ServiceB.method4()時,一切都很好,因此通常應在第一次嘗試中退出。

我希望這個例子能說明Spring AOP在現實世界中有足夠的用處:-)

翻譯自: https://www.javacodegeeks.com/2016/02/retrying-method-execution-using-spring-aop.html

spring aop不執行

總結

以上是生活随笔為你收集整理的spring aop不执行_使用Spring AOP重试方法执行的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。