支持在 Bean 方法(必须保证入参和返回值符合 ReturnT<String> 方法名任意(String param) throws Exception)上使用 @JobHandler 注解,在方法上使用注解时如果没有指定 value,就会使用方法名作为 JobHandler 的名字,注解额外增加 init 和 destroy 可以指定当前 bean 中的其他方法作为 JobHandler 中的 init 和 destroy 方法。

master
abel533 5 years ago
parent 82bb3dfcc8
commit 039346b730
  1. 39
      xxl-job-core/src/main/java/com/xxl/job/core/executor/impl/XxlJobSpringExecutor.java
  2. 14
      xxl-job-core/src/main/java/com/xxl/job/core/handler/annotation/JobHandler.java
  3. 97
      xxl-job-core/src/main/java/com/xxl/job/core/handler/impl/MethodJobHandler.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<String, Object> 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;
}

@ -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 "";
}

@ -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<String> execute(String param) throws Exception {
return (ReturnT<String>) 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;
}
}
Loading…
Cancel
Save