通过注解及AOP实现xxl-job入参解析
一 注解类
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Job {
/**
* @return job枚举
*/
JobEnum jobEnum();
/**
* @return 是否存在job参数
*/
boolean isJobParam() default true;
/**
* @return job参数在方法参数中的序号,默认为第一个参数(isJobParam == true时生效)
*/
int jobParamIndex() default 0;
}
二 AOP实现参数解析
/**
* Job 注解切面实现
* 添加job日志,以及封装xxljob参数
*/
@Aspect
@Component
public class JobAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(JobAspect.class);
private static final String JOB_LOGGER_ANNOTATION = "com.test.support.job.Job";
private static final String XXL_JOB_PACKAGE = "com.test.job";
/**
* 定义JobLogger切面
*/
@Pointcut("@annotation(" + JOB_LOGGER_ANNOTATION + ")")
public void taskAspect() {
// do nothing
}
/**
* JobLogger切面具体逻辑
* 1.打印日志
* 2.获取入参
* @param joinPoint 切点
* @param job JobLogger注解
* @throws Throwable 异常
*/
@Around("taskAspect() && @annotation(job)")
public void around(ProceedingJoinPoint joinPoint, Job job) throws Throwable {
XxlJobHelper.log("[{}]任务开始", job.jobEnum().getJobName());
LOGGER.info("[{}]任务开始", job.jobEnum().getJobName());
try {
Object[] args = joinPoint.getArgs();
if (ObjectUtils.isNotEmpty(args) && job.isJobParam() && this.isXxlJobInvoke()) {
String jobParam = XxlJobHelper.getJobParam();
LOGGER.info("[{}]任务入参[{}]", job.jobEnum().getJobName(), jobParam);
args[job.jobParamIndex()] = JobUtil.buildJobParam(job.jobEnum(), jobParam);
}
joinPoint.proceed(args);
XxlJobHelper.log("[{}]任务结束", job.jobEnum().getJobName());
LOGGER.info("[{}]任务结束", job.jobEnum().getJobName());
} catch (Exception e) {
XxlJobHelper.log("[{}]任务异常", job.jobEnum().getJobName());
LOGGER.error("[{}]任务异常", job.jobEnum().getJobName(), e);
throw e;
}
}
/**
* 判断是否xxljob调用
* @return true:xxljob调用
*/
private boolean isXxlJobInvoke() {
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace) {
if (stackTraceElement.getClassName().contains(XXL_JOB_PACKAGE)) {
return true;
}
}
return false;
}
}
三 参数解析工具类
public class JobUtil {
private JobUtil() {}
public static IJobParam buildJobParam(JobEnum jobEnum, String jobParam) throws DocumentException,
NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
if (StringUtils.isBlank(jobParam)) {
return null;
}
if (JobParamTypeEnum.XML.equals(jobEnum.getParamTypeEnum())) {
Document document = DocumentHelper.parseText(jobParam);
if (document == null) {
return null;
}
return jobEnum.getParamClass().getConstructor(Document.class).newInstance(document);
} else if (JobParamTypeEnum.JSON.equals(jobEnum.getParamTypeEnum())) {
return JSONObject.parseObject(jobParam, jobEnum.getParamClass());
}
return null;
}
}
四 参数基类接口
public interface IJobParam extends Serializable {
}
五 xml参数类示例
@Getter
@Setter
public class TestParam implements IJobParam {
private String a;
public TestParam(Document document) {
this.a = document.valueOf("/root/参数A");
}
}
六 注解使用
@XxlJob("test")
@Job(jobEnum = JobEnum.TEST)
public void test(TestParam param) throws Exception {
testService.test(param);
}