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

2.1.2
xuxueli 5 years ago
parent 49f7e16954
commit f083bb2695

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

@ -1,9 +1,11 @@
package com.xxl.job.core.executor.impl; package com.xxl.job.core.executor.impl;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.executor.XxlJobExecutor; import com.xxl.job.core.executor.XxlJobExecutor;
import com.xxl.job.core.glue.GlueFactory; import com.xxl.job.core.glue.GlueFactory;
import com.xxl.job.core.handler.IJobHandler; import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.JobHandler; import com.xxl.job.core.handler.annotation.JobHandler;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.handler.impl.MethodJobHandler; import com.xxl.job.core.handler.impl.MethodJobHandler;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.DisposableBean;
@ -29,11 +31,13 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
// init JobHandler Repository // init JobHandler Repository
initJobHandlerRepository(applicationContext); initJobHandlerRepository(applicationContext);
// init JobHandler Repository (for method)
initJobHandlerMethodRepository(applicationContext); initJobHandlerMethodRepository(applicationContext);
// refresh GlueFactory // refresh GlueFactory
GlueFactory.refreshInstance(1); GlueFactory.refreshInstance(1);
// super start // super start
super.start(); super.start();
} }
@ -71,21 +75,59 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
if (applicationContext == null) { if (applicationContext == null) {
return; return;
} }
// init job handler from method
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames(); String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) { for (String beanDefinitionName : beanDefinitionNames) {
Object bean = applicationContext.getBean(beanDefinitionName); Object bean = applicationContext.getBean(beanDefinitionName);
Method[] methods = bean.getClass().getDeclaredMethods(); Method[] methods = bean.getClass().getDeclaredMethods();
for (int i = 0; i < methods.length; i++) { for (Method method: methods) {
JobHandler jobHandler = AnnotationUtils.findAnnotation(methods[i], JobHandler.class); XxlJob xxlJob = AnnotationUtils.findAnnotation(method, XxlJob.class);
if (jobHandler != null) { if (xxlJob != null) {
String name = jobHandler.value();
if (name.isEmpty()) { // name
name = methods[i].getName(); 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) { if (loadJobHandler(name) != null) {
throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts."); throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts.");
} }
registJobHandler(name, new MethodJobHandler(bean, methods[i], jobHandler));
// 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() +"] .");
}
}
// registry jobhandler
registJobHandler(name, new MethodJobHandler(bean, method, initMethod, destroyMethod));
} }
} }
} }

@ -2,6 +2,8 @@ package com.xxl.job.core.handler;
import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.biz.model.ReturnT;
import java.lang.reflect.InvocationTargetException;
/** /**
* job handler * job handler
* *
@ -31,7 +33,7 @@ public abstract class IJobHandler {
/** /**
* init handler, invoked when JobThread init * init handler, invoked when JobThread init
*/ */
public void init() { public void init() throws InvocationTargetException, IllegalAccessException {
// do something // do something
} }
@ -39,7 +41,7 @@ public abstract class IJobHandler {
/** /**
* destroy handler, invoked when JobThread destroy * destroy handler, invoked when JobThread destroy
*/ */
public void destroy() { public void destroy() throws InvocationTargetException, IllegalAccessException {
// do something // do something
} }

@ -8,23 +8,16 @@ import java.lang.annotation.Target;
/** /**
* annotation for job handler * annotation for job handler
*
*
* @author 2016-5-17 21:06:49 * @author 2016-5-17 21:06:49
* @author liuzh 2019-12-07
*/ */
@Target({ElementType.TYPE, ElementType.METHOD}) @Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Inherited @Inherited
@Deprecated
public @interface JobHandler { public @interface JobHandler {
String value() default ""; String value() default "";
/**
* init handler, invoked when JobThread init
*/
String init() default "";
/**
* destroy handler, invoked when JobThread destroy
*/
String destroy() default "";
} }

@ -0,0 +1,30 @@
package com.xxl.job.core.handler.annotation;
import java.lang.annotation.*;
/**
* annotation for method jobhandler
*
* @author xuxueli 2019-12-11 20:50:13
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface XxlJob {
/**
* jobhandler name
*/
String value() default "";
/**
* init handler, invoked when JobThread init
*/
String init() default "";
/**
* destroy handler, invoked when JobThread destroy
*/
String destroy() default "";
}

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

@ -2,52 +2,26 @@ package com.xxl.job.core.handler.impl;
import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler; 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.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
/** /**
* @author liuzh 2019-12-07 * @author xuxueli 2019-12-11 21:12:18
*/ */
public class MethodJobHandler extends IJobHandler { public class MethodJobHandler extends IJobHandler {
private static Logger logger = LoggerFactory.getLogger(MethodJobHandler.class);
private final Object target; private final Object target;
private final Method method; private final Method method;
private final JobHandler jobHandler;
private Method initMethod; private Method initMethod;
private Method destroyMethod; private Method destroyMethod;
public MethodJobHandler(Object target, Method method, JobHandler jobHandler) { public MethodJobHandler(Object target, Method method, Method initMethod, Method destroyMethod) {
this.target = target; this.target = target;
this.method = method; this.method = method;
this.jobHandler = jobHandler;
this.method.setAccessible(true);
this.prepareMethod();
}
protected void prepareMethod() { this.initMethod =initMethod;
String init = jobHandler.init(); this.destroyMethod =destroyMethod;
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 @Override
@ -56,42 +30,21 @@ public class MethodJobHandler extends IJobHandler {
} }
@Override @Override
public void init() { public void init() throws InvocationTargetException, IllegalAccessException {
super.init();
if(initMethod != null) { if(initMethod != null) {
try {
initMethod.invoke(target); initMethod.invoke(target);
} catch (IllegalAccessException e) {
logger.warn(e.getMessage(), e);
} catch (InvocationTargetException e) {
logger.warn(e.getMessage(), e);
}
} }
} }
@Override @Override
public void destroy() { public void destroy() throws InvocationTargetException, IllegalAccessException {
super.destroy();
if(destroyMethod != null) { if(destroyMethod != null) {
try {
destroyMethod.invoke(target); 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() { @Override
return method; public String toString() {
} return super.toString()+"["+ target.getClass() + "#" + method.getName() +"]";
public JobHandler getJobHandler() {
return jobHandler;
} }
} }

@ -10,6 +10,8 @@ import java.util.concurrent.TimeUnit;
/** /**
* com.xxl.job.executor.service.jobhandler.SampleXxlJob
*
* HandlerBean * HandlerBean
* *
* *

@ -0,0 +1,44 @@
package com.xxl.job.executor.service.jobhandler;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import org.springframework.stereotype.Component;
/**
* XxlJobBean
*
*
* 1Spring BeanJob "public ReturnT<String> execute(String param)"
* 2Job "@XxlJob(value="jobhandler", init = "JobHandler", destroy = "JobHandler")"valueJobHandler
* 3 "XxlJobLogger.log"
*
* @author xuxueli 2019-12-11 21:52:51
*/
@Component
public class SampleXxlJob {
@XxlJob("demoJobHandler2")
public ReturnT<String> execute(String param) {
XxlJobLogger.log("222");
return ReturnT.SUCCESS;
}
@XxlJob(value="demoJobHandler3", init = "init", destroy = "destory")
public ReturnT<String> execute3(String param) {
XxlJobLogger.log("333");
return ReturnT.SUCCESS;
}
public void init(){
System.out.println("init");
}
public void destory(){
System.out.println("destory");
}
}
Loading…
Cancel
Save