瀏覽代碼

Merge pull request #1383 from LiZhenNet/master

refactor:修改获取XxlJob注解方法的方式
许雪里 5 年之前
父節點
當前提交
5f6eee85f8
共有 1 個文件被更改,包括 73 次插入52 次删除
  1. 73 52
      xxl-job-core/src/main/java/com/xxl/job/core/executor/impl/XxlJobSpringExecutor.java

+ 73 - 52
xxl-job-core/src/main/java/com/xxl/job/core/executor/impl/XxlJobSpringExecutor.java

@@ -5,21 +5,29 @@ import com.xxl.job.core.executor.XxlJobExecutor;
 import com.xxl.job.core.glue.GlueFactory;
 import com.xxl.job.core.handler.annotation.XxlJob;
 import com.xxl.job.core.handler.impl.MethodJobHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
-import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.core.MethodIntrospector;
+import org.springframework.core.annotation.AnnotatedElementUtils;
 
 import java.lang.reflect.Method;
 
+import java.util.HashMap;
+import java.util.Map;
+
+
 /**
  * xxl-job executor (for spring)
  *
  * @author xuxueli 2018-11-01 09:24:52
  */
 public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationContextAware, InitializingBean, DisposableBean {
+    private static final Logger logger = LoggerFactory.getLogger(XxlJobSpringExecutor.class);
 
 
     // start
@@ -72,62 +80,75 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
         if (applicationContext == null) {
             return;
         }
-
         // init job handler from method
-        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
-        if (beanDefinitionNames!=null && beanDefinitionNames.length>0) {
-            for (String beanDefinitionName : beanDefinitionNames) {
-                Object bean = applicationContext.getBean(beanDefinitionName);
-                Method[] methods = bean.getClass().getDeclaredMethods();
-                for (Method method: methods) {
-                    XxlJob xxlJob = AnnotationUtils.findAnnotation(method, XxlJob.class);
-                    if (xxlJob != null) {
-
-                        // name
-                        String name = xxlJob.value();
-                        if (name.trim().length() == 0) {
-                            throw new RuntimeException("xxl-job method-jobhandler name invalid, for[" + bean.getClass() + "#"+ method.getName() +"] .");
-                        }
-                        if (loadJobHandler(name) != null) {
-                            throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts.");
-                        }
-
-                        // execute method
-                        if (!(method.getParameterTypes()!=null && method.getParameterTypes().length==1 && method.getParameterTypes()[0].isAssignableFrom(String.class))) {
-                            throw new RuntimeException("xxl-job method-jobhandler param-classtype invalid, for[" + bean.getClass() + "#"+ method.getName() +"] , " +
-                                    "The correct method format like \" public ReturnT<String> execute(String param) \" .");
-                        }
-                        if (!method.getReturnType().isAssignableFrom(ReturnT.class)) {
-                            throw new RuntimeException("xxl-job method-jobhandler return-classtype invalid, for[" + bean.getClass() + "#"+ method.getName() +"] , " +
-                                    "The correct method format like \" public ReturnT<String> execute(String param) \" .");
-                        }
-                        method.setAccessible(true);
-
-                        // init and destory
-                        Method initMethod = null;
-                        Method destroyMethod = null;
-
-                        if(xxlJob.init().trim().length() > 0) {
-                            try {
-                                initMethod = bean.getClass().getDeclaredMethod(xxlJob.init());
-                                initMethod.setAccessible(true);
-                            } catch (NoSuchMethodException e) {
-                                throw new RuntimeException("xxl-job method-jobhandler initMethod invalid, for[" + bean.getClass() + "#"+ method.getName() +"] .");
-                            }
-                        }
-                        if(xxlJob.destroy().trim().length() > 0) {
-                            try {
-                                destroyMethod = bean.getClass().getDeclaredMethod(xxlJob.destroy());
-                                destroyMethod.setAccessible(true);
-                            } catch (NoSuchMethodException e) {
-                                throw new RuntimeException("xxl-job method-jobhandler destroyMethod invalid, for[" + bean.getClass() + "#"+ method.getName() +"] .");
+
+        String[] beanDefinitionNames = applicationContext.getBeanNamesForType(Object.class, false, true);
+        for (String beanDefinitionName : beanDefinitionNames) {
+            Object bean = applicationContext.getBean(beanDefinitionName);
+
+            Map<Method, XxlJob> annotatedMethods = new HashMap<>();
+            try {
+                annotatedMethods = MethodIntrospector.selectMethods(bean.getClass(),
+                        new MethodIntrospector.MetadataLookup<XxlJob>() {
+                            @Override
+                            public XxlJob inspect(Method method) {
+                                return AnnotatedElementUtils.findMergedAnnotation(method, XxlJob.class);
                             }
-                        }
+                        });
+            } catch (Throwable ex) {
+                if (logger.isDebugEnabled()) {
+                    logger.debug("Could not resolve methods for bean with name '" + beanDefinitionName + "'", ex);
+                }
+            }
+
+            for (Map.Entry<Method, XxlJob> methodXxlJobEntry : annotatedMethods.entrySet()) {
+                Method method = methodXxlJobEntry.getKey();
+                XxlJob xxlJob = methodXxlJobEntry.getValue();
+                if (xxlJob == null) {
+                    continue;
+                }
+                String name = xxlJob.value();
+                if (name.trim().length() == 0) {
+                    throw new RuntimeException("xxl-job method-jobhandler name invalid, for[" + bean.getClass() + "#" + method.getName() + "] .");
+                }
+                if (loadJobHandler(name) != null) {
+                    throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts.");
+                }
 
-                        // registry jobhandler
-                        registJobHandler(name, new MethodJobHandler(bean, method, initMethod, destroyMethod));
+                // execute method
+                if (!(method.getParameterTypes().length == 1 && method.getParameterTypes()[0].isAssignableFrom(String.class))) {
+                    throw new RuntimeException("xxl-job method-jobhandler param-classtype invalid, for[" + bean.getClass() + "#" + method.getName() + "] , " +
+                            "The correct method format like \" public ReturnT<String> execute(String param) \" .");
+                }
+                if (!method.getReturnType().isAssignableFrom(ReturnT.class)) {
+                    throw new RuntimeException("xxl-job method-jobhandler return-classtype invalid, for[" + bean.getClass() + "#" + method.getName() + "] , " +
+                            "The correct method format like \" public ReturnT<String> execute(String param) \" .");
+                }
+                method.setAccessible(true);
+
+                // init and destory
+                Method initMethod = null;
+                Method destroyMethod = null;
+
+                if (xxlJob.init().trim().length() > 0) {
+                    try {
+                        initMethod = bean.getClass().getDeclaredMethod(xxlJob.init());
+                        initMethod.setAccessible(true);
+                    } catch (NoSuchMethodException e) {
+                        throw new RuntimeException("xxl-job method-jobhandler initMethod invalid, for[" + bean.getClass() + "#" + method.getName() + "] .");
+                    }
+                }
+                if (xxlJob.destroy().trim().length() > 0) {
+                    try {
+                        destroyMethod = bean.getClass().getDeclaredMethod(xxlJob.destroy());
+                        destroyMethod.setAccessible(true);
+                    } catch (NoSuchMethodException e) {
+                        throw new RuntimeException("xxl-job method-jobhandler destroyMethod invalid, for[" + bean.getClass() + "#" + method.getName() + "] .");
                     }
                 }
+
+                // registry jobhandler
+                registJobHandler(name, new MethodJobHandler(bean, method, initMethod, destroyMethod));
             }
         }