From 039346b730cd7b792c1ce1caff67d7ed1c2ba4b0 Mon Sep 17 00:00:00 2001 From: abel533 Date: Sat, 7 Dec 2019 16:45:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9C=A8=20Bean=20=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=88=E5=BF=85=E9=A1=BB=E4=BF=9D=E8=AF=81=E5=85=A5?= =?UTF-8?q?=E5=8F=82=E5=92=8C=E8=BF=94=E5=9B=9E=E5=80=BC=E7=AC=A6=E5=90=88?= =?UTF-8?q?=20ReturnT=20=E6=96=B9=E6=B3=95=E5=90=8D=E4=BB=BB?= =?UTF-8?q?=E6=84=8F(String=20param)=20throws=20Exception=EF=BC=89?= =?UTF-8?q?=E4=B8=8A=E4=BD=BF=E7=94=A8=20@JobHandler=20=E6=B3=A8=E8=A7=A3?= =?UTF-8?q?=EF=BC=8C=E5=9C=A8=E6=96=B9=E6=B3=95=E4=B8=8A=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=B3=A8=E8=A7=A3=E6=97=B6=E5=A6=82=E6=9E=9C=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=20value=EF=BC=8C=E5=B0=B1=E4=BC=9A=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E6=96=B9=E6=B3=95=E5=90=8D=E4=BD=9C=E4=B8=BA=20JobHan?= =?UTF-8?q?dler=20=E7=9A=84=E5=90=8D=E5=AD=97=EF=BC=8C=E6=B3=A8=E8=A7=A3?= =?UTF-8?q?=E9=A2=9D=E5=A4=96=E5=A2=9E=E5=8A=A0=20init=20=E5=92=8C=20destr?= =?UTF-8?q?oy=20=E5=8F=AF=E4=BB=A5=E6=8C=87=E5=AE=9A=E5=BD=93=E5=89=8D=20b?= =?UTF-8?q?ean=20=E4=B8=AD=E7=9A=84=E5=85=B6=E4=BB=96=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E4=BD=9C=E4=B8=BA=20JobHandler=20=E4=B8=AD=E7=9A=84=20init=20?= =?UTF-8?q?=E5=92=8C=20destroy=20=E6=96=B9=E6=B3=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../executor/impl/XxlJobSpringExecutor.java | 39 +++++++- .../core/handler/annotation/JobHandler.java | 14 ++- .../core/handler/impl/MethodJobHandler.java | 97 +++++++++++++++++++ 3 files changed, 143 insertions(+), 7 deletions(-) create mode 100644 xxl-job-core/src/main/java/com/xxl/job/core/handler/impl/MethodJobHandler.java diff --git a/xxl-job-core/src/main/java/com/xxl/job/core/executor/impl/XxlJobSpringExecutor.java b/xxl-job-core/src/main/java/com/xxl/job/core/executor/impl/XxlJobSpringExecutor.java index d0a14824..6f128a6a 100644 --- a/xxl-job-core/src/main/java/com/xxl/job/core/executor/impl/XxlJobSpringExecutor.java +++ b/xxl-job-core/src/main/java/com/xxl/job/core/executor/impl/XxlJobSpringExecutor.java @@ -4,12 +4,15 @@ import com.xxl.job.core.executor.XxlJobExecutor; import com.xxl.job.core.glue.GlueFactory; import com.xxl.job.core.handler.IJobHandler; import com.xxl.job.core.handler.annotation.JobHandler; +import com.xxl.job.core.handler.impl.MethodJobHandler; 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 java.lang.reflect.Method; import java.util.Map; /** @@ -26,7 +29,7 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC // init JobHandler Repository initJobHandlerRepository(applicationContext); - + initJobHandlerMethodRepository(applicationContext); // refresh GlueFactory GlueFactory.refreshInstance(1); @@ -42,7 +45,7 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC } - private void initJobHandlerRepository(ApplicationContext applicationContext){ + private void initJobHandlerRepository(ApplicationContext applicationContext) { if (applicationContext == null) { return; } @@ -50,13 +53,13 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC // init job handler action Map serviceBeanMap = applicationContext.getBeansWithAnnotation(JobHandler.class); - if (serviceBeanMap!=null && serviceBeanMap.size()>0) { + if (serviceBeanMap != null && serviceBeanMap.size() > 0) { for (Object serviceBean : serviceBeanMap.values()) { - if (serviceBean instanceof IJobHandler){ + if (serviceBean instanceof IJobHandler) { String name = serviceBean.getClass().getAnnotation(JobHandler.class).value(); IJobHandler handler = (IJobHandler) serviceBean; if (loadJobHandler(name) != null) { - throw new RuntimeException("xxl-job jobhandler["+ name +"] naming conflicts."); + throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts."); } registJobHandler(name, handler); } @@ -64,12 +67,38 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC } } + private void initJobHandlerMethodRepository(ApplicationContext applicationContext) { + if (applicationContext == null) { + return; + } + String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames(); + for (String beanDefinitionName : beanDefinitionNames) { + Object bean = applicationContext.getBean(beanDefinitionName); + Method[] methods = bean.getClass().getDeclaredMethods(); + for (int i = 0; i < methods.length; i++) { + JobHandler jobHandler = AnnotationUtils.findAnnotation(methods[i], JobHandler.class); + if (jobHandler != null) { + String name = jobHandler.value(); + if (name.isEmpty()) { + name = methods[i].getName(); + } + if (loadJobHandler(name) != null) { + throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts."); + } + registJobHandler(name, new MethodJobHandler(bean, methods[i], jobHandler)); + } + } + } + } + // ---------------------- applicationContext ---------------------- private static ApplicationContext applicationContext; + @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } + public static ApplicationContext getApplicationContext() { return applicationContext; } diff --git a/xxl-job-core/src/main/java/com/xxl/job/core/handler/annotation/JobHandler.java b/xxl-job-core/src/main/java/com/xxl/job/core/handler/annotation/JobHandler.java index 253026a4..d6ba1e3e 100644 --- a/xxl-job-core/src/main/java/com/xxl/job/core/handler/annotation/JobHandler.java +++ b/xxl-job-core/src/main/java/com/xxl/job/core/handler/annotation/JobHandler.java @@ -9,12 +9,22 @@ import java.lang.annotation.Target; /** * annotation for job handler * @author 2016-5-17 21:06:49 + * @author liuzh 2019-12-07 */ -@Target({ElementType.TYPE}) +@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface JobHandler { String value() default ""; - + + /** + * init handler, invoked when JobThread init + */ + String init() default ""; + + /** + * destroy handler, invoked when JobThread destroy + */ + String destroy() default ""; } diff --git a/xxl-job-core/src/main/java/com/xxl/job/core/handler/impl/MethodJobHandler.java b/xxl-job-core/src/main/java/com/xxl/job/core/handler/impl/MethodJobHandler.java new file mode 100644 index 00000000..b9753a79 --- /dev/null +++ b/xxl-job-core/src/main/java/com/xxl/job/core/handler/impl/MethodJobHandler.java @@ -0,0 +1,97 @@ +package com.xxl.job.core.handler.impl; + +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.IJobHandler; +import com.xxl.job.core.handler.annotation.JobHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * @author liuzh 2019-12-07 + */ +public class MethodJobHandler extends IJobHandler { + private static Logger logger = LoggerFactory.getLogger(MethodJobHandler.class); + + private final Object target; + private final Method method; + private final JobHandler jobHandler; + private Method initMethod; + private Method destroyMethod; + + public MethodJobHandler(Object target, Method method, JobHandler jobHandler) { + this.target = target; + this.method = method; + this.jobHandler = jobHandler; + this.method.setAccessible(true); + this.prepareMethod(); + } + + protected void prepareMethod() { + String init = jobHandler.init(); + if(!init.isEmpty()) { + try { + initMethod = target.getClass().getDeclaredMethod(init); + initMethod.setAccessible(true); + } catch (NoSuchMethodException e) { + logger.warn(e.getMessage(), e); + } + } + String destroy = jobHandler.destroy(); + if(!destroy.isEmpty()) { + try { + destroyMethod = target.getClass().getDeclaredMethod(destroy); + destroyMethod.setAccessible(true); + } catch (NoSuchMethodException e) { + logger.warn(e.getMessage(), e); + } + } + } + + @Override + public ReturnT execute(String param) throws Exception { + return (ReturnT) method.invoke(target, new Object[]{param}); + } + + @Override + public void init() { + super.init(); + if(initMethod != null) { + try { + initMethod.invoke(target); + } catch (IllegalAccessException e) { + logger.warn(e.getMessage(), e); + } catch (InvocationTargetException e) { + logger.warn(e.getMessage(), e); + } + } + } + + @Override + public void destroy() { + super.destroy(); + if(destroyMethod != null) { + try { + destroyMethod.invoke(target); + } catch (IllegalAccessException e) { + logger.warn(e.getMessage(), e); + } catch (InvocationTargetException e) { + logger.warn(e.getMessage(), e); + } + } + } + + public Object getTarget() { + return target; + } + + public Method getMethod() { + return method; + } + + public JobHandler getJobHandler() { + return jobHandler; + } +}