java重试两种实现方式

1、java重试两种实现方式

1.1 模板方法

定义模板类

RetryTemplate

package com.mine.template;

public abstract class RetryTemplate {
	// 重试次数
	private int retryTime = 5;

	// 重试的睡眠时间
	private int sleepTime = 3000;

	public void setSleepTime(int sleepTime) {
		this.sleepTime = sleepTime;
	}

	public void setRetryTime(int retryTime) {
		this.retryTime = retryTime;
	}

	protected abstract void doAction() throws Exception;

	public void execute() throws Exception {
		for (int i = 0; i < retryTime; i++) {
			try {
				doAction();
				return;
			} catch (Exception e) {
				Thread.sleep(sleepTime);
			}
		}
	}
}

测试类

TestRetryTemplate

package com.mine.template;

public class TestRetryTemplate extends RetryTemplate {
	private int i = 1;

	@Override
	protected void doAction() throws Exception {
		System.out.println("----------------");
		System.out.println(System.currentTimeMillis());
		if (i++ >= 3) {
			System.out.println("sucess");
		} else {
			System.out.println("failure");
			throw new Exception();
		}
	}

	public static void main(String[] args) throws Exception {
		new TestRetryTemplate().execute();
	}
}

1.2 使用Spring AOP

1.2.1 引入依赖

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0modelVersion>
	<groupId>com.minegroupId>
	<artifactId>retry-testartifactId>
	<version>0.0.1-SNAPSHOTversion>

	<parent>
		<groupId>org.springframework.bootgroupId>
		<artifactId>spring-boot-starter-parentartifactId>
		<version>2.0.3.RELEASEversion>
	parent>

	<dependencies>
		
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-webartifactId>
		dependency>

		<dependency>
			<groupId>org.projectlombokgroupId>
			<artifactId>lombokartifactId>
		dependency>

		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-aopartifactId>
		dependency>

		
		
		<dependency>
			<groupId>org.slf4jgroupId>
			<artifactId>log4j-over-slf4jartifactId>
		dependency>
		
		<dependency>
			<groupId>org.slf4jgroupId>
			<artifactId>jcl-over-slf4jartifactId>
		dependency>
		
		<dependency>
			<groupId>org.slf4jgroupId>
			<artifactId>jul-to-slf4jartifactId>
		dependency>
		
	dependencies>
project>

1.2.2 注解

ExceptionRetry

package com.mine.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExceptionRetry {
	/**
	 * 重试次数
	 * 
	 * @return
	 */
	int count() default 5;

	/**
	 * 重试的间隔时间
	 * 
	 * @return
	 */
	int sleep() default 3000;
}

1.2.3 切面

ExceptionRetryAspect

package com.mine.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.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import com.mine.annotation.ExceptionRetry;

import lombok.extern.slf4j.Slf4j;

@Aspect
@Component
@Slf4j
public class ExceptionRetryAspect {
	@Pointcut("@annotation(com.mine.annotation.ExceptionRetry)")
	public void retryPointCut() {
	}

	@Around("retryPointCut()")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
		Method method = methodSignature.getMethod();
		ExceptionRetry retry = method.getAnnotation(ExceptionRetry.class);
		String name = method.getName();
		int count = retry.count();
		long sleep = retry.sleep();

		if (count <= 0) {
			count = 1;
		}

		if (sleep <= 0) {
			sleep = 3000;
		}

		for (int i = 1; i <= count; i++) {
			try {
				Object obj = joinPoint.proceed();
				log.info("第" + i + "次执行方法【" + name + "】成功!");
				return obj;
			} catch (Exception e) {
				log.error("第" + i + "次执行方法【" + name + "】失败!");

				if (i == count) {
					throw e;
				}

				Thread.sleep(sleep);
			}
		}
		return null;
	}
}

1.2.4 测试类编写

TestRetryService

package com.mine.service;

import org.springframework.stereotype.Service;

import com.mine.annotation.ExceptionRetry;

@Service
public class TestRetryService {
	@ExceptionRetry
	public String test(String param) {
		Integer parseInt = Integer.valueOf(param);
		return "success" + parseInt;
	}
}

TestRetryController

package com.mine.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.mine.service.TestRetryService;

@RestController
public class TestRetryController {
	@Autowired
	private TestRetryService testRetryService;
	
	@RequestMapping("/index")
	public String index(String param) {
		testRetryService.test(param);
		return "success";
	}
}

App

package com.mine;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}

}

1.2.5 启动与测试

启动APP类

分别访问下面链接地址

http://localhost:8080/index?param=a

http://localhost:8080/index?param=1

你可能感兴趣的:(spring)