Przeglądaj źródła

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

xuxueli 5 lat temu
rodzic
commit
f083bb2695

+ 13 - 4
doc/XXL-JOB官方文档.md Wyświetl plik

1630
 - 25、项目依赖升级至较新稳定版本,如spring、spring-boot、mybatis、slf4j、groovy等等;
1630
 - 25、项目依赖升级至较新稳定版本,如spring、spring-boot、mybatis、slf4j、groovy等等;
1631
 
1631
 
1632
 ### 6.27 版本 v2.1.2 Release Notes[迭代中]
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
 ### TODO LIST
1648
 ### TODO LIST

+ 50 - 8
xxl-job-core/src/main/java/com/xxl/job/core/executor/impl/XxlJobSpringExecutor.java Wyświetl plik

1
 package com.xxl.job.core.executor.impl;
1
 package com.xxl.job.core.executor.impl;
2
 
2
 
3
+import com.xxl.job.core.biz.model.ReturnT;
3
 import com.xxl.job.core.executor.XxlJobExecutor;
4
 import com.xxl.job.core.executor.XxlJobExecutor;
4
 import com.xxl.job.core.glue.GlueFactory;
5
 import com.xxl.job.core.glue.GlueFactory;
5
 import com.xxl.job.core.handler.IJobHandler;
6
 import com.xxl.job.core.handler.IJobHandler;
6
 import com.xxl.job.core.handler.annotation.JobHandler;
7
 import com.xxl.job.core.handler.annotation.JobHandler;
8
+import com.xxl.job.core.handler.annotation.XxlJob;
7
 import com.xxl.job.core.handler.impl.MethodJobHandler;
9
 import com.xxl.job.core.handler.impl.MethodJobHandler;
8
 import org.springframework.beans.BeansException;
10
 import org.springframework.beans.BeansException;
9
 import org.springframework.beans.factory.DisposableBean;
11
 import org.springframework.beans.factory.DisposableBean;
29
 
31
 
30
         // init JobHandler Repository
32
         // init JobHandler Repository
31
         initJobHandlerRepository(applicationContext);
33
         initJobHandlerRepository(applicationContext);
34
+
35
+        // init JobHandler Repository (for method)
32
         initJobHandlerMethodRepository(applicationContext);
36
         initJobHandlerMethodRepository(applicationContext);
37
+
33
         // refresh GlueFactory
38
         // refresh GlueFactory
34
         GlueFactory.refreshInstance(1);
39
         GlueFactory.refreshInstance(1);
35
 
40
 
36
-
37
         // super start
41
         // super start
38
         super.start();
42
         super.start();
39
     }
43
     }
71
         if (applicationContext == null) {
75
         if (applicationContext == null) {
72
             return;
76
             return;
73
         }
77
         }
78
+
79
+        // init job handler from method
74
         String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
80
         String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
75
         for (String beanDefinitionName : beanDefinitionNames) {
81
         for (String beanDefinitionName : beanDefinitionNames) {
76
             Object bean = applicationContext.getBean(beanDefinitionName);
82
             Object bean = applicationContext.getBean(beanDefinitionName);
77
             Method[] methods = bean.getClass().getDeclaredMethods();
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
                     if (loadJobHandler(name) != null) {
93
                     if (loadJobHandler(name) != null) {
86
                         throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts.");
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 Wyświetl plik

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

+ 4 - 11
xxl-job-core/src/main/java/com/xxl/job/core/handler/annotation/JobHandler.java Wyświetl plik

8
 
8
 
9
 /**
9
 /**
10
  * annotation for job handler
10
  * annotation for job handler
11
+ *
12
+ *
11
  * @author 2016-5-17 21:06:49
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
 @Retention(RetentionPolicy.RUNTIME)
16
 @Retention(RetentionPolicy.RUNTIME)
16
 @Inherited
17
 @Inherited
18
+@Deprecated
17
 public @interface JobHandler {
19
 public @interface JobHandler {
18
 
20
 
19
     String value() default "";
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 Wyświetl plik

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 Wyświetl plik

6
 
6
 
7
 /**
7
 /**
8
  * glue job handler
8
  * glue job handler
9
+ *
9
  * @author xuxueli 2016-5-19 21:05:45
10
  * @author xuxueli 2016-5-19 21:05:45
10
  */
11
  */
11
 public class GlueJobHandler extends IJobHandler {
12
 public class GlueJobHandler extends IJobHandler {

+ 11 - 58
xxl-job-core/src/main/java/com/xxl/job/core/handler/impl/MethodJobHandler.java Wyświetl plik

2
 
2
 
3
 import com.xxl.job.core.biz.model.ReturnT;
3
 import com.xxl.job.core.biz.model.ReturnT;
4
 import com.xxl.job.core.handler.IJobHandler;
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
 import java.lang.reflect.InvocationTargetException;
6
 import java.lang.reflect.InvocationTargetException;
10
 import java.lang.reflect.Method;
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
 public class MethodJobHandler extends IJobHandler {
12
 public class MethodJobHandler extends IJobHandler {
16
-    private static Logger logger = LoggerFactory.getLogger(MethodJobHandler.class);
17
 
13
 
18
     private final Object target;
14
     private final Object target;
19
     private final Method method;
15
     private final Method method;
20
-    private final JobHandler jobHandler;
21
     private Method initMethod;
16
     private Method initMethod;
22
     private Method destroyMethod;
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
         this.target = target;
20
         this.target = target;
26
         this.method = method;
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
     @Override
27
     @Override
56
     }
30
     }
57
 
31
 
58
     @Override
32
     @Override
59
-    public void init() {
60
-        super.init();
33
+    public void init() throws InvocationTargetException, IllegalAccessException {
61
         if(initMethod != null) {
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
     @Override
39
     @Override
73
-    public void destroy() {
74
-        super.destroy();
40
+    public void destroy() throws InvocationTargetException, IllegalAccessException {
75
         if(destroyMethod != null) {
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 Wyświetl plik

10
 
10
 
11
 
11
 
12
 /**
12
 /**
13
+ * 【类方式任务开发即将废弃,建议采用方法方式开发,参考:com.xxl.job.executor.service.jobhandler.SampleXxlJob 】
14
+ *
13
  * 任务Handler示例(Bean模式)
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 Wyświetl plik

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
+}