From 8e413db8d12116a9d3458955fa2d5c0ab4632d3e Mon Sep 17 00:00:00 2001 From: redkale Date: Tue, 19 Dec 2023 16:48:37 +0800 Subject: [PATCH] ScheduleEvent --- .../org/redkale/schedule/ScheduleEvent.java | 76 +++++++++++++++++++ .../java/org/redkale/schedule/Scheduled.java | 2 +- .../schedule/spi/ScheduleManagerService.java | 29 +++++-- 3 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 src/main/java/org/redkale/schedule/ScheduleEvent.java diff --git a/src/main/java/org/redkale/schedule/ScheduleEvent.java b/src/main/java/org/redkale/schedule/ScheduleEvent.java new file mode 100644 index 000000000..d0132d8cc --- /dev/null +++ b/src/main/java/org/redkale/schedule/ScheduleEvent.java @@ -0,0 +1,76 @@ +/* + * + */ +package org.redkale.schedule; + +import java.util.HashMap; +import java.util.Map; +import org.redkale.convert.json.JsonConvert; +import org.redkale.util.Utility; + +/** + * 定时任务的参数 + * + * + *

+ * 详情见: https://redkale.org + * + * @author zhangjx + * + * @since 2.8.0 + */ +public class ScheduleEvent { + + private final Map map; + + public ScheduleEvent() { + this.map = new HashMap<>(); + } + + public ScheduleEvent(Map map) { + this.map = map; + } + + @SuppressWarnings("unchecked") + public T get(String name) { + return (T) map.get(name); + } + + public String getString(String name) { + return Utility.convertValue(String.class, map.get(name)); + } + + public Integer getInteger(String name) { + return Utility.convertValue(int.class, map.get(name)); + } + + public Long getLong(String name) { + return Utility.convertValue(Long.class, map.get(name)); + } + + public int getInt(String name, int defValue) { + Object val = map.get(name); + if (val == null) { + return defValue; + } + return Utility.convertValue(int.class, val); + } + + public long getLong(String name, long defValue) { + Object val = map.get(name); + if (val == null) { + return defValue; + } + return Utility.convertValue(long.class, val); + } + + public ScheduleEvent clear() { + map.clear(); + return this; + } + + @Override + public String toString() { + return JsonConvert.root().convertTo(this); + } +} diff --git a/src/main/java/org/redkale/schedule/Scheduled.java b/src/main/java/org/redkale/schedule/Scheduled.java index a6ad1b0d9..e0ffd285e 100644 --- a/src/main/java/org/redkale/schedule/Scheduled.java +++ b/src/main/java/org/redkale/schedule/Scheduled.java @@ -7,7 +7,7 @@ import java.lang.annotation.*; import java.util.concurrent.TimeUnit; /** - * 定时任务标记,只能作用于Service的无参数方法上, 功能类似Spring里的Scheduled注解 + * 定时任务标记,只能作用于Service的无参数或者单一ScheduleEvent参数的方法上, 功能类似Spring里的Scheduled注解 * * *

diff --git a/src/main/java/org/redkale/schedule/spi/ScheduleManagerService.java b/src/main/java/org/redkale/schedule/spi/ScheduleManagerService.java index c36463898..6eb231b95 100644 --- a/src/main/java/org/redkale/schedule/spi/ScheduleManagerService.java +++ b/src/main/java/org/redkale/schedule/spi/ScheduleManagerService.java @@ -22,6 +22,7 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; import java.util.function.UnaryOperator; import java.util.logging.Level; @@ -32,6 +33,7 @@ import org.redkale.annotation.Nullable; import org.redkale.annotation.Resource; import org.redkale.annotation.ResourceType; import org.redkale.boot.Application; +import org.redkale.schedule.ScheduleEvent; import org.redkale.schedule.ScheduleManager; import org.redkale.schedule.Scheduled; import org.redkale.service.Local; @@ -142,6 +144,7 @@ public class ScheduleManagerService implements ScheduleManager, Service { Map tasks = new LinkedHashMap<>(); Class clazz = service.getClass(); WeakReference ref = new WeakReference(service); + AtomicInteger taskCount = new AtomicInteger(); do { for (final Method method : clazz.getDeclaredMethods()) { if (method.getAnnotation(Scheduled.class) == null) { @@ -150,10 +153,12 @@ public class ScheduleManagerService implements ScheduleManager, Service { if (tasks.containsKey(method.getName())) { continue; } - if (method.getParameterCount() > 0) { - throw new RedkaleException("@" + Scheduled.class.getSimpleName() + " must be on non-parameter method, but on " + method); + if (method.getParameterCount() != 0 + && (method.getParameterCount() == 1 && method.getParameterTypes()[0] == ScheduleEvent.class)) { + throw new RedkaleException("@" + Scheduled.class.getSimpleName() + + " must be on non-parameter or " + ScheduleEvent.class.getSimpleName() + "-parameter method, but on " + method); } - ScheduledTask task = schedule(ref, method); + ScheduledTask task = schedule(ref, method, taskCount); if (task == null) { continue; //时间都没配置 } @@ -166,7 +171,7 @@ public class ScheduleManagerService implements ScheduleManager, Service { tasks.forEach((name, task) -> task.start()); refTaskMap.put(ref, new ArrayList<>(tasks.values())); } - return !tasks.isEmpty(); + return taskCount.get() > 0; } finally { lock.unlock(); } @@ -195,7 +200,7 @@ public class ScheduleManagerService implements ScheduleManager, Service { } } - protected ScheduledTask schedule(WeakReference ref, Method method) { + protected ScheduledTask schedule(WeakReference ref, Method method, AtomicInteger taskCount) { Scheduled ann = method.getAnnotation(Scheduled.class); String name = getProperty(ann.name()); String cron = getProperty(ann.cron()); @@ -204,9 +209,16 @@ public class ScheduleManagerService implements ScheduleManager, Service { String initialDelay = getProperty(ann.initialDelay()); String zone = getProperty(ann.zone()); TimeUnit timeUnit = ann.timeUnit(); + return scheduleTask(ref, method, taskCount, name, cron, fixedDelay, fixedRate, initialDelay, zone, timeUnit); + } + + protected ScheduledTask scheduleTask(WeakReference ref, Method method, AtomicInteger taskCount, + String name, String cron, String fixedDelay, String fixedRate, + String initialDelay, String zone, TimeUnit timeUnit) { if ((cron.isEmpty() || "-".equals(cron)) && "-1".equals(fixedRate) && "-1".endsWith(fixedDelay)) { return null; //时间都没配置 } + taskCount.incrementAndGet(); ZoneId zoneId = Utility.isEmpty(zone) ? null : ZoneId.of(zone); if (!cron.isEmpty() && !"-".equals(cron)) { CronExpression cronExpr = CronExpression.parse(cron); @@ -225,11 +237,16 @@ public class ScheduleManagerService implements ScheduleManager, Service { method.setAccessible(true); } MethodHandle mh = MethodHandles.lookup().unreflect(method); + ScheduleEvent event = method.getParameterCount() == 1 ? new ScheduleEvent() : null; return () -> { try { Object obj = ref.get(); if (obj != null) { - mh.invoke(obj); + if (event == null) { + mh.invoke(obj); + } else { + mh.invoke(obj, event.clear()); + } } } catch (Throwable t) { logger.log(Level.SEVERE, "schedule task error", t);