Bläddra i källkod

Merge pull request #1338 from abel533/method

许雪里 5 år sedan
förälder
incheckning
4e578759e1

+ 34 - 5
xxl-job-core/src/main/java/com/xxl/job/core/executor/impl/XxlJobSpringExecutor.java Visa fil

4
 import com.xxl.job.core.glue.GlueFactory;
4
 import com.xxl.job.core.glue.GlueFactory;
5
 import com.xxl.job.core.handler.IJobHandler;
5
 import com.xxl.job.core.handler.IJobHandler;
6
 import com.xxl.job.core.handler.annotation.JobHandler;
6
 import com.xxl.job.core.handler.annotation.JobHandler;
7
+import com.xxl.job.core.handler.impl.MethodJobHandler;
7
 import org.springframework.beans.BeansException;
8
 import org.springframework.beans.BeansException;
8
 import org.springframework.beans.factory.DisposableBean;
9
 import org.springframework.beans.factory.DisposableBean;
9
 import org.springframework.beans.factory.InitializingBean;
10
 import org.springframework.beans.factory.InitializingBean;
10
 import org.springframework.context.ApplicationContext;
11
 import org.springframework.context.ApplicationContext;
11
 import org.springframework.context.ApplicationContextAware;
12
 import org.springframework.context.ApplicationContextAware;
13
+import org.springframework.core.annotation.AnnotationUtils;
12
 
14
 
15
+import java.lang.reflect.Method;
13
 import java.util.Map;
16
 import java.util.Map;
14
 
17
 
15
 /**
18
 /**
26
 
29
 
27
         // init JobHandler Repository
30
         // init JobHandler Repository
28
         initJobHandlerRepository(applicationContext);
31
         initJobHandlerRepository(applicationContext);
29
-
32
+        initJobHandlerMethodRepository(applicationContext);
30
         // refresh GlueFactory
33
         // refresh GlueFactory
31
         GlueFactory.refreshInstance(1);
34
         GlueFactory.refreshInstance(1);
32
 
35
 
42
     }
45
     }
43
 
46
 
44
 
47
 
45
-    private void initJobHandlerRepository(ApplicationContext applicationContext){
48
+    private void initJobHandlerRepository(ApplicationContext applicationContext) {
46
         if (applicationContext == null) {
49
         if (applicationContext == null) {
47
             return;
50
             return;
48
         }
51
         }
50
         // init job handler action
53
         // init job handler action
51
         Map<String, Object> serviceBeanMap = applicationContext.getBeansWithAnnotation(JobHandler.class);
54
         Map<String, Object> serviceBeanMap = applicationContext.getBeansWithAnnotation(JobHandler.class);
52
 
55
 
53
-        if (serviceBeanMap!=null && serviceBeanMap.size()>0) {
56
+        if (serviceBeanMap != null && serviceBeanMap.size() > 0) {
54
             for (Object serviceBean : serviceBeanMap.values()) {
57
             for (Object serviceBean : serviceBeanMap.values()) {
55
-                if (serviceBean instanceof IJobHandler){
58
+                if (serviceBean instanceof IJobHandler) {
56
                     String name = serviceBean.getClass().getAnnotation(JobHandler.class).value();
59
                     String name = serviceBean.getClass().getAnnotation(JobHandler.class).value();
57
                     IJobHandler handler = (IJobHandler) serviceBean;
60
                     IJobHandler handler = (IJobHandler) serviceBean;
58
                     if (loadJobHandler(name) != null) {
61
                     if (loadJobHandler(name) != null) {
59
-                        throw new RuntimeException("xxl-job jobhandler["+ name +"] naming conflicts.");
62
+                        throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts.");
60
                     }
63
                     }
61
                     registJobHandler(name, handler);
64
                     registJobHandler(name, handler);
62
                 }
65
                 }
64
         }
67
         }
65
     }
68
     }
66
 
69
 
70
+    private void initJobHandlerMethodRepository(ApplicationContext applicationContext) {
71
+        if (applicationContext == null) {
72
+            return;
73
+        }
74
+        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
75
+        for (String beanDefinitionName : beanDefinitionNames) {
76
+            Object bean = applicationContext.getBean(beanDefinitionName);
77
+            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
+                    }
85
+                    if (loadJobHandler(name) != null) {
86
+                        throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts.");
87
+                    }
88
+                    registJobHandler(name, new MethodJobHandler(bean, methods[i], jobHandler));
89
+                }
90
+            }
91
+        }
92
+    }
93
+
67
     // ---------------------- applicationContext ----------------------
94
     // ---------------------- applicationContext ----------------------
68
     private static ApplicationContext applicationContext;
95
     private static ApplicationContext applicationContext;
96
+
69
     @Override
97
     @Override
70
     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
98
     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
71
         this.applicationContext = applicationContext;
99
         this.applicationContext = applicationContext;
72
     }
100
     }
101
+
73
     public static ApplicationContext getApplicationContext() {
102
     public static ApplicationContext getApplicationContext() {
74
         return applicationContext;
103
         return applicationContext;
75
     }
104
     }

+ 12 - 2
xxl-job-core/src/main/java/com/xxl/job/core/handler/annotation/JobHandler.java Visa fil

9
 /**
9
 /**
10
  * annotation for job handler
10
  * annotation for job handler
11
  * @author 2016-5-17 21:06:49
11
  * @author 2016-5-17 21:06:49
12
+ * @author liuzh 2019-12-07
12
  */
13
  */
13
-@Target({ElementType.TYPE})
14
+@Target({ElementType.TYPE, ElementType.METHOD})
14
 @Retention(RetentionPolicy.RUNTIME)
15
 @Retention(RetentionPolicy.RUNTIME)
15
 @Inherited
16
 @Inherited
16
 public @interface JobHandler {
17
 public @interface JobHandler {
17
 
18
 
18
     String value() default "";
19
     String value() default "";
19
-    
20
+
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 "";
20
 }
30
 }

+ 97 - 0
xxl-job-core/src/main/java/com/xxl/job/core/handler/impl/MethodJobHandler.java Visa fil

1
+package com.xxl.job.core.handler.impl;
2
+
3
+import com.xxl.job.core.biz.model.ReturnT;
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
+
9
+import java.lang.reflect.InvocationTargetException;
10
+import java.lang.reflect.Method;
11
+
12
+/**
13
+ * @author liuzh 2019-12-07
14
+ */
15
+public class MethodJobHandler extends IJobHandler {
16
+    private static Logger logger = LoggerFactory.getLogger(MethodJobHandler.class);
17
+
18
+    private final Object target;
19
+    private final Method method;
20
+    private final JobHandler jobHandler;
21
+    private Method initMethod;
22
+    private Method destroyMethod;
23
+
24
+    public MethodJobHandler(Object target, Method method, JobHandler jobHandler) {
25
+        this.target = target;
26
+        this.method = method;
27
+        this.jobHandler = jobHandler;
28
+        this.method.setAccessible(true);
29
+        this.prepareMethod();
30
+    }
31
+
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
+        }
51
+    }
52
+
53
+    @Override
54
+    public ReturnT<String> execute(String param) throws Exception {
55
+        return (ReturnT<String>) method.invoke(target, new Object[]{param});
56
+    }
57
+
58
+    @Override
59
+    public void init() {
60
+        super.init();
61
+        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
+            }
69
+        }
70
+    }
71
+
72
+    @Override
73
+    public void destroy() {
74
+        super.destroy();
75
+        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
+            }
83
+        }
84
+    }
85
+
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;
96
+    }
97
+}