在使用Elasticsearch时,发现做了增删改查后,数据需要定时更新。于是就自己写了一个简易的定时器(不过并没有应用到项目中,因为主流框架中都有集成,但是我并不喜欢cron表达式)。以下是定时器的实现以及测试代码:
1.定义Timer注解
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;
/**
* @author caojianyu
* @create 2019-12-26 11:20
* @mail jieni_cao@foxmail.com
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Timer {
public String hour() default "0";
public String minutes() default "0";
public String seconds() default "0";
}
2.定义时间转换常量值
/**
* @author caojianyu
* @create 2020-01-15 19:01
* @mail jieni_cao@foxmail.com
*
*/
public final class TimeConstant {
public static final Long HOUR_TRANSLATE = 3600000L;
public static final Long MINUTES_TRANSLATE = 60000L;
public static final Long SECONDS_TRANSLATE = 1000L;
}
3.将时间转换为秒的方法
import com.yuanma.timer.constant.TimeConstant;
/**
* @author caojianyu
* @create 2020-01-15 19:01
* @mail jieni_cao@foxmail.com
*
*/
public class Transform {
private static final Long ZERO = 0L;
public static Long getTimeInterval(Long hour, Long minutes, Long seconds) {
Long timeInterval = 0L;
if (ZERO.equals(hour) && ZERO.equals(minutes) && ZERO.equals(seconds)) {
throw new NullPointerException("定时器时间间隔未设置");
}
if (!ZERO.equals(hour) && ZERO.equals(minutes) && ZERO.equals(seconds)) {
timeInterval = hour * TimeConstant.HOUR_TRANSLATE;
} else if (ZERO.equals(hour) && !ZERO.equals(minutes) && ZERO.equals(seconds)) {
timeInterval = minutes * TimeConstant.MINUTES_TRANSLATE;
} else if (ZERO.equals(hour) && ZERO.equals(minutes) && !ZERO.equals(seconds)) {
timeInterval = seconds * 1000L;
} else if (!ZERO.equals(hour) && !ZERO.equals(minutes) && ZERO.equals(seconds)) {
timeInterval = hour * TimeConstant.HOUR_TRANSLATE + minutes * TimeConstant.MINUTES_TRANSLATE;
} else if (!ZERO.equals(hour) && ZERO.equals(minutes) && !ZERO.equals(seconds)) {
timeInterval = hour * TimeConstant.HOUR_TRANSLATE + seconds * TimeConstant.SECONDS_TRANSLATE;
} else if (ZERO.equals(hour) && !ZERO.equals(minutes) && !ZERO.equals(seconds)) {
timeInterval = minutes * TimeConstant.MINUTES_TRANSLATE + seconds * TimeConstant.SECONDS_TRANSLATE;
} else {
timeInterval = hour * TimeConstant.HOUR_TRANSLATE + minutes * TimeConstant.MINUTES_TRANSLATE
+ seconds * TimeConstant.SECONDS_TRANSLATE;
}
return timeInterval;
}
}
4.执行定时任务的方法
import java.lang.reflect.*;
/**
* @author caojianyu
* @create 2019-12-26 11:20
* @mail jieni_cao@foxmail.com
*
*/
public class Processor {
public static void process(Class<?> clazz) {
Runnable runnable = new Runnable() {
public void run() {
boolean isTrue = false;
isTrue = clazz.isAnnotationPresent(Timer.class);
if (isTrue) {
Timer getAnnotation = clazz.getAnnotation(Timer.class);
Long hour = Long.parseLong(getAnnotation.hour());
Long minutes = Long.parseLong(getAnnotation.minutes());
Long seconds = Long.parseLong(getAnnotation.seconds());
Long timeInterval = Transform.getTimeInterval(hour, minutes, seconds);
while (true) {
for (Method method : clazz.getDeclaredMethods()) {
Constructor<?> con;
try {
con = clazz.getConstructor();
method.invoke(con.newInstance());
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
| InstantiationException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(timeInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
new Thread(runnable).start();
}
}
5.基本框架也就搭好了,接下来创建一个测试类用于测试
使用时,在需要定时执行任务的类上加一个@Timer注解,并指定时间间隔参数(也就是注解定义的那几个参数)——共有三个参数:hour小时,minutes分钟,seconds秒。
@Timer(seconds = "2")
public class Test {
public void print() {
System.out.println("测试方法正在定时运行...");
}
}
6.再创建一个主函数测试
public class TestTimer {
public static void main(String[] args) {
Processor.process(Test.class);
}
}
我设置的为两秒,所以是每两秒种运行一次,如果小时和分钟有设置值,则会叠加。使用可直接打成jar包引用到项目中。以下是运行结果:
测试方法正在定时运行…
测试方法正在定时运行…
测试方法正在定时运行…