Procházet zdrojové kódy

方法任务支持:由原来基于JobHandler类任务开发方式,优化为支持基于方法的任务开发方式;因此,可以支持单个类中开发多个任务方法,进行类复用

xuxueli před 5 roky
rodič
revize
f083bb2695

+ 13 - 4
doc/XXL-JOB官方文档.md Zobrazit soubor

@@ -1630,10 +1630,19 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
1630 1630
 - 25、项目依赖升级至较新稳定版本,如spring、spring-boot、mybatis、slf4j、groovy等等;
1631 1631
 
1632 1632
 ### 6.27 版本 v2.1.2 Release Notes[迭代中]
1633
-- 1、调度中心dispatcher servlet加载顺序优化;
1634
-- 2、执行器回调乱码问题修复;
1635
-- 3、[迭代中]移除commons-exec,采用原生方式实现;
1636
-- 4、[迭代中]任务操作API服务调整为restful方式,降低接入成本;
1633
+- 1、方法任务支持:由原来基于JobHandler类任务开发方式,优化为支持基于方法的任务开发方式;因此,可以支持单个类中开发多个任务方法,进行类复用(TODO:JobHandler移除);
1634
+```
1635
+@XxlJob("demoJobHandler2")
1636
+public ReturnT<String> execute(String param) {
1637
+    XxlJobLogger.log("hello world");
1638
+    return ReturnT.SUCCESS;
1639
+}
1640
+```
1641
+- 2、调度中心dispatcher servlet加载顺序优化;
1642
+- 3、执行器回调乱码问题修复;
1643
+- 4、[迭代中]移除commons-exec,采用原生方式实现;
1644
+- 5、[迭代中]任务操作API服务调整为restful方式,降低接入成本;
1645
+
1637 1646
 
1638 1647
 
1639 1648
 ### TODO LIST

+ 50 - 8
xxl-job-core/src/main/java/com/xxl/job/core/executor/impl/XxlJobSpringExecutor.java Zobrazit soubor

@@ -1,9 +1,11 @@
1 1
 package com.xxl.job.core.executor.impl;
2 2
 
3
+import com.xxl.job.core.biz.model.ReturnT;
3 4
 import com.xxl.job.core.executor.XxlJobExecutor;
4 5
 import com.xxl.job.core.glue.GlueFactory;
5 6
 import com.xxl.job.core.handler.IJobHandler;
6 7
 import com.xxl.job.core.handler.annotation.JobHandler;
8
+import com.xxl.job.core.handler.annotation.XxlJob;
7 9
 import com.xxl.job.core.handler.impl.MethodJobHandler;
8 10
 import org.springframework.beans.BeansException;
9 11
 import org.springframework.beans.factory.DisposableBean;
@@ -29,11 +31,13 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
29 31
 
30 32
         // init JobHandler Repository
31 33
         initJobHandlerRepository(applicationContext);
34
+
35
+        // init JobHandler Repository (for method)
32 36
         initJobHandlerMethodRepository(applicationContext);
37
+
33 38
         // refresh GlueFactory
34 39
         GlueFactory.refreshInstance(1);
35 40
 
36
-
37 41
         // super start
38 42
         super.start();
39 43
     }
@@ -71,21 +75,59 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
71 75
         if (applicationContext == null) {
72 76
             return;
73 77
         }
78
+
79
+        // init job handler from method
74 80
         String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
75 81
         for (String beanDefinitionName : beanDefinitionNames) {
76 82
             Object bean = applicationContext.getBean(beanDefinitionName);
77 83
             Method[] methods = bean.getClass().getDeclaredMethods();
78
-            for (int i = 0; i < methods.length; i++) {
79
-                JobHandler jobHandler = AnnotationUtils.findAnnotation(methods[i], JobHandler.class);
80
-                if (jobHandler != null) {
81
-                    String name = jobHandler.value();
82
-                    if (name.isEmpty()) {
83
-                        name = methods[i].getName();
84
+            for (Method method: methods) {
85
+                XxlJob xxlJob = AnnotationUtils.findAnnotation(method, XxlJob.class);
86
+                if (xxlJob != null) {
87
+
88
+                    // name
89
+                    String name = xxlJob.value();
90
+                    if (name.trim().length() == 0) {
91
+                        throw new RuntimeException("xxl-job method-jobhandler name invalid, for[" + bean.getClass() + "#"+ method.getName() +"] .");
84 92
                     }
85 93
                     if (loadJobHandler(name) != null) {
86 94
                         throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts.");
87 95
                     }
88
-                    registJobHandler(name, new MethodJobHandler(bean, methods[i], jobHandler));
96
+
97
+                    // execute method
98
+                    if (!(method.getParameterTypes()!=null && method.getParameterTypes().length==1 && method.getParameterTypes()[0].isAssignableFrom(String.class))) {
99
+                        throw new RuntimeException("xxl-job method-jobhandler param-classtype invalid, for[" + bean.getClass() + "#"+ method.getName() +"] , " +
100
+                                "The correct method format like \" public ReturnT<String> execute(String param) \" .");
101
+                    }
102
+                    if (!method.getReturnType().isAssignableFrom(ReturnT.class)) {
103
+                        throw new RuntimeException("xxl-job method-jobhandler return-classtype invalid, for[" + bean.getClass() + "#"+ method.getName() +"] , " +
104
+                                "The correct method format like \" public ReturnT<String> execute(String param) \" .");
105
+                    }
106
+                    method.setAccessible(true);
107
+
108
+                    // init and destory
109
+                    Method initMethod = null;
110
+                    Method destroyMethod = null;
111
+
112
+                    if(xxlJob.init().trim().length() > 0) {
113
+                        try {
114
+                            initMethod = bean.getClass().getDeclaredMethod(xxlJob.init());
115
+                            initMethod.setAccessible(true);
116
+                        } catch (NoSuchMethodException e) {
117
+                            throw new RuntimeException("xxl-job method-jobhandler initMethod invalid, for[" + bean.getClass() + "#"+ method.getName() +"] .");
118
+                        }
119
+                    }
120
+                    if(xxlJob.destroy().trim().length() > 0) {
121
+                        try {
122
+                            destroyMethod = bean.getClass().getDeclaredMethod(xxlJob.destroy());
123
+                            destroyMethod.setAccessible(true);
124
+                        } catch (NoSuchMethodException e) {
125
+                            throw new RuntimeException("xxl-job method-jobhandler destroyMethod invalid, for[" + bean.getClass() + "#"+ method.getName() +"] .");
126
+                        }
127
+                    }
128
+
129
+                    // registry jobhandler
130
+                    registJobHandler(name, new MethodJobHandler(bean, method, initMethod, destroyMethod));
89 131
                 }
90 132
             }
91 133
         }

+ 4 - 2
xxl-job-core/src/main/java/com/xxl/job/core/handler/IJobHandler.java Zobrazit soubor

@@ -2,6 +2,8 @@ package com.xxl.job.core.handler;
2 2
 
3 3
 import com.xxl.job.core.biz.model.ReturnT;
4 4
 
5
+import java.lang.reflect.InvocationTargetException;
6
+
5 7
 /**
6 8
  * job handler
7 9
  *
@@ -31,7 +33,7 @@ public abstract class IJobHandler {
31 33
 	/**
32 34
 	 * init handler, invoked when JobThread init
33 35
 	 */
34
-	public void init() {
36
+	public void init() throws InvocationTargetException, IllegalAccessException {
35 37
 		// do something
36 38
 	}
37 39
 
@@ -39,7 +41,7 @@ public abstract class IJobHandler {
39 41
 	/**
40 42
 	 * destroy handler, invoked when JobThread destroy
41 43
 	 */
42
-	public void destroy() {
44
+	public void destroy() throws InvocationTargetException, IllegalAccessException {
43 45
 		// do something
44 46
 	}
45 47
 

+ 4 - 11
xxl-job-core/src/main/java/com/xxl/job/core/handler/annotation/JobHandler.java Zobrazit soubor

@@ -8,23 +8,16 @@ import java.lang.annotation.Target;
8 8
 
9 9
 /**
10 10
  * annotation for job handler
11
+ *
12
+ *
11 13
  * @author 2016-5-17 21:06:49
12
- * @author liuzh 2019-12-07
13 14
  */
14
-@Target({ElementType.TYPE, ElementType.METHOD})
15
+@Target({ElementType.TYPE})
15 16
 @Retention(RetentionPolicy.RUNTIME)
16 17
 @Inherited
18
+@Deprecated
17 19
 public @interface JobHandler {
18 20
 
19 21
     String value() default "";
20 22
 
21
-    /**
22
-     * init handler, invoked when JobThread init
23
-     */
24
-    String init() default "";
25
-
26
-    /**
27
-     * destroy handler, invoked when JobThread destroy
28
-     */
29
-    String destroy() default "";
30 23
 }

+ 30 - 0
xxl-job-core/src/main/java/com/xxl/job/core/handler/annotation/XxlJob.java Zobrazit soubor

@@ -0,0 +1,30 @@
1
+package com.xxl.job.core.handler.annotation;
2
+
3
+import java.lang.annotation.*;
4
+
5
+/**
6
+ * annotation for method jobhandler
7
+ *
8
+ * @author xuxueli 2019-12-11 20:50:13
9
+ */
10
+@Target({ElementType.METHOD})
11
+@Retention(RetentionPolicy.RUNTIME)
12
+@Inherited
13
+public @interface XxlJob {
14
+
15
+    /**
16
+     * jobhandler name
17
+     */
18
+    String value() default "";
19
+
20
+    /**
21
+     * init handler, invoked when JobThread init
22
+     */
23
+    String init() default "";
24
+
25
+    /**
26
+     * destroy handler, invoked when JobThread destroy
27
+     */
28
+    String destroy() default "";
29
+
30
+}

+ 1 - 0
xxl-job-core/src/main/java/com/xxl/job/core/handler/impl/GlueJobHandler.java Zobrazit soubor

@@ -6,6 +6,7 @@ import com.xxl.job.core.log.XxlJobLogger;
6 6
 
7 7
 /**
8 8
  * glue job handler
9
+ *
9 10
  * @author xuxueli 2016-5-19 21:05:45
10 11
  */
11 12
 public class GlueJobHandler extends IJobHandler {

+ 11 - 58
xxl-job-core/src/main/java/com/xxl/job/core/handler/impl/MethodJobHandler.java Zobrazit soubor

@@ -2,52 +2,26 @@ package com.xxl.job.core.handler.impl;
2 2
 
3 3
 import com.xxl.job.core.biz.model.ReturnT;
4 4
 import com.xxl.job.core.handler.IJobHandler;
5
-import com.xxl.job.core.handler.annotation.JobHandler;
6
-import org.slf4j.Logger;
7
-import org.slf4j.LoggerFactory;
8 5
 
9 6
 import java.lang.reflect.InvocationTargetException;
10 7
 import java.lang.reflect.Method;
11 8
 
12 9
 /**
13
- * @author liuzh 2019-12-07
10
+ * @author xuxueli 2019-12-11 21:12:18
14 11
  */
15 12
 public class MethodJobHandler extends IJobHandler {
16
-    private static Logger logger = LoggerFactory.getLogger(MethodJobHandler.class);
17 13
 
18 14
     private final Object target;
19 15
     private final Method method;
20
-    private final JobHandler jobHandler;
21 16
     private Method initMethod;
22 17
     private Method destroyMethod;
23 18
 
24
-    public MethodJobHandler(Object target, Method method, JobHandler jobHandler) {
19
+    public MethodJobHandler(Object target, Method method, Method initMethod, Method destroyMethod) {
25 20
         this.target = target;
26 21
         this.method = method;
27
-        this.jobHandler = jobHandler;
28
-        this.method.setAccessible(true);
29
-        this.prepareMethod();
30
-    }
31 22
 
32
-    protected void prepareMethod() {
33
-        String init = jobHandler.init();
34
-        if(!init.isEmpty()) {
35
-            try {
36
-                initMethod = target.getClass().getDeclaredMethod(init);
37
-                initMethod.setAccessible(true);
38
-            } catch (NoSuchMethodException e) {
39
-                logger.warn(e.getMessage(), e);
40
-            }
41
-        }
42
-        String destroy = jobHandler.destroy();
43
-        if(!destroy.isEmpty()) {
44
-            try {
45
-                destroyMethod = target.getClass().getDeclaredMethod(destroy);
46
-                destroyMethod.setAccessible(true);
47
-            } catch (NoSuchMethodException e) {
48
-                logger.warn(e.getMessage(), e);
49
-            }
50
-        }
23
+        this.initMethod =initMethod;
24
+        this.destroyMethod =destroyMethod;
51 25
     }
52 26
 
53 27
     @Override
@@ -56,42 +30,21 @@ public class MethodJobHandler extends IJobHandler {
56 30
     }
57 31
 
58 32
     @Override
59
-    public void init() {
60
-        super.init();
33
+    public void init() throws InvocationTargetException, IllegalAccessException {
61 34
         if(initMethod != null) {
62
-            try {
63
-                initMethod.invoke(target);
64
-            } catch (IllegalAccessException e) {
65
-                logger.warn(e.getMessage(), e);
66
-            } catch (InvocationTargetException e) {
67
-                logger.warn(e.getMessage(), e);
68
-            }
35
+            initMethod.invoke(target);
69 36
         }
70 37
     }
71 38
 
72 39
     @Override
73
-    public void destroy() {
74
-        super.destroy();
40
+    public void destroy() throws InvocationTargetException, IllegalAccessException {
75 41
         if(destroyMethod != null) {
76
-            try {
77
-                destroyMethod.invoke(target);
78
-            } catch (IllegalAccessException e) {
79
-                logger.warn(e.getMessage(), e);
80
-            } catch (InvocationTargetException e) {
81
-                logger.warn(e.getMessage(), e);
82
-            }
42
+            destroyMethod.invoke(target);
83 43
         }
84 44
     }
85 45
 
86
-    public Object getTarget() {
87
-        return target;
88
-    }
89
-
90
-    public Method getMethod() {
91
-        return method;
92
-    }
93
-
94
-    public JobHandler getJobHandler() {
95
-        return jobHandler;
46
+    @Override
47
+    public String toString() {
48
+        return super.toString()+"["+ target.getClass() + "#" + method.getName() +"]";
96 49
     }
97 50
 }

+ 2 - 0
xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/java/com/xxl/job/executor/service/jobhandler/DemoJobHandler.java Zobrazit soubor

@@ -10,6 +10,8 @@ import java.util.concurrent.TimeUnit;
10 10
 
11 11
 
12 12
 /**
13
+ * 【类方式任务开发即将废弃,建议采用方法方式开发,参考:com.xxl.job.executor.service.jobhandler.SampleXxlJob 】
14
+ *
13 15
  * 任务Handler示例(Bean模式)
14 16
  *
15 17
  * 开发步骤:

+ 44 - 0
xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/java/com/xxl/job/executor/service/jobhandler/SampleXxlJob.java Zobrazit soubor

@@ -0,0 +1,44 @@
1
+package com.xxl.job.executor.service.jobhandler;
2
+
3
+import com.xxl.job.core.biz.model.ReturnT;
4
+import com.xxl.job.core.handler.annotation.XxlJob;
5
+import com.xxl.job.core.log.XxlJobLogger;
6
+import org.springframework.stereotype.Component;
7
+
8
+/**
9
+ * XxlJob开发示例(Bean模式)
10
+ *
11
+ * 开发步骤:
12
+ * 1、在Spring Bean实例中,开发Job方法,方式格式要求为 "public ReturnT<String> execute(String param)"
13
+ * 2、为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。
14
+ * 3、执行日志:需要通过 "XxlJobLogger.log" 打印执行日志;
15
+ *
16
+ * @author xuxueli 2019-12-11 21:52:51
17
+ */
18
+@Component
19
+public class SampleXxlJob {
20
+
21
+
22
+    @XxlJob("demoJobHandler2")
23
+    public ReturnT<String> execute(String param) {
24
+
25
+        XxlJobLogger.log("222");
26
+        return ReturnT.SUCCESS;
27
+    }
28
+
29
+    @XxlJob(value="demoJobHandler3", init = "init", destroy = "destory")
30
+    public ReturnT<String> execute3(String param) {
31
+
32
+        XxlJobLogger.log("333");
33
+        return ReturnT.SUCCESS;
34
+    }
35
+
36
+    public void init(){
37
+        System.out.println("init");
38
+    }
39
+
40
+    public void destory(){
41
+        System.out.println("destory");
42
+    }
43
+
44
+}