xxl-job使用遇到的问题(二)

关联阅读 xxl-job使用遇到的问题(一)

1、问题现象

最近有个老定时任务迁移到xxl-job的时候,遇到一个小问题。虽然很快解决,但是还是有必要记录一下~

job迁移的时候,在执行方法上标记@XxlJob("test"),然后在管理控制台上,添加任务,点击执行一次的时候,调度日志提示

>>>>>>>>>>>触发调度<<<<<<<<<<<

触发调度:

address:http://10.25.31.45:9999/

code:500

msg:job handler [test] not found.

检查了下代码,没啥问题。注解加了,XxlJobSpringExecutor也有,properties配置也ok,为啥提示找不到呢?

大致代码也贴一下

public interface ITestJob {
void method1();
} @Service
public class TestJobImpl implements ITestJob { @XxlJob("test")
public ReturnT<String> demoJobHandler() throws Exception {
// job业务逻辑【历史代码】
return ReturnT.SUCCESS;
} // 历史代码方法
@Override
@Async
public void method1() {
// 历史代码逻辑
}
}

其实就是在历史代码的基础上,改了下方法返回值,加了个@XxlJob("test")注解。其他没动

2、排查

既然提示找不到job handler,那问题肯定是出在客户端了。

前面阅读源码的时候,已经看过,@XxlJob注解的解析是在 XxlJobSpringExecutor类里面。快读看了下这个类,重点看了下initJobHandlerMethodRepository方法

private void initJobHandlerMethodRepository(ApplicationContext applicationContext) {
if (applicationContext == null) {
return;
}
// init job handler from method
String[] beanDefinitionNames = applicationContext.getBeanNamesForType(Object.class, false, true);
for (String beanDefinitionName : beanDefinitionNames) {
Object bean = applicationContext.getBean(beanDefinitionName); Map<Method, XxlJob> annotatedMethods = null; // referred to :org.springframework.context.event.EventListenerMethodProcessor.processBean
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) {
logger.error("xxl-job method-jobhandler resolve error for bean[" + beanDefinitionName + "].", ex);
}
if (annotatedMethods==null || annotatedMethods.isEmpty()) {
continue;
} ...... }

在这块加个断点看看,果然拿到的 annotatedMethods 是空的,难怪提示找不到呢!

3、原因

上面的demoJobHandler方法头上标记了注解的,为什么annotatedMethods是空的呢?

这是因为下面这行代码取到的bean,不是TestJobImpl这个类

Object bean = applicationContext.getBean(beanDefinitionName);

而是一个代理类,并且是jdk的动态代理的类。

jdk动态代理,啥特性?

嗯,基于接口的~~,接口里面只申明了一个方法 method1,那【MethodIntrospector.selectMethods】肯定找不到有XxlJob注解的方法了!

3.1、 解决办法

知道了这一点,那就好解决了。

可供参考的解决办法:

方法一、把job这个方法单独拎出来

方法二、去掉接口,让Spring使用cglib的代理。这样取到的代理类就包含2个方法了,就可以找到有注解的那个方法了

方法三、如果上面2个都不想改,那就在接口里面申明一个demoJobHandler方法,并且在接口方法申明上标记@XxlJob("test")注解

xxl-job使用遇到的问题(二)的更多相关文章

  1. 分布式消息队列XXL-MQ

    <分布式消息队列XXL-MQ>     一.简介 1.1 概述 XXL-MQ是一款轻量级分布式消息队列,支持串行.并行和广播等多种消息模型.现已开放源代码,开箱即用. 支持三种消息模式: ...

  2. java web学习总结(二十八) -------------------JSP中的JavaBean

    一.什么是JavaBean JavaBean是一个遵循特定写法的Java类,它通常具有如下特点: 这个Java类必须具有一个无参的构造函数 属性必须私有化. 私有化的属性必须通过public类型的方法 ...

  3. javaweb学习总结(二十)——JavaBean总结

    一.什么是JavaBean JavaBean是一个遵循特定写法的Java类,它通常具有如下特点: 这个Java类必须具有一个无参的构造函数 属性必须私有化. 私有化的属性必须通过public类型的方法 ...

  4. 初识Selenium(二)

    ---------------------------------------------------------------------------------------------------- ...

  5. javaweb(二十)——JavaBean总结

    一.什么是JavaBean JavaBean是一个遵循特定写法的Java类,它通常具有如下特点: 这个Java类必须具有一个无参的构造函数 属性必须私有化. 私有化的属性必须通过public类型的方法 ...

  6. python驱动SAP完成数据导出(二)

    在上一篇 python驱动SAP完成数据导出(一)中,我们提到了数据导出前,SAP布局的重要性,如何识别当前布局模式,以及如何切换到想要的布局.本篇小爬将着重讲讲数据导出的注意事项. 我们可以通过如下 ...

  7. SpringCloud微服务实战——搭建企业级开发框架(四十二):集成分布式任务调度平台XXL-JOB,实现定时任务功能

      定时任务几乎是每个业务系统必不可少的功能,计算到期时间.过期时间等,定时触发某项任务操作.在使用单体应用时,基本使用Spring提供的注解即可实现定时任务,而在使用微服务集群时,这种方式就要考虑添 ...

  8. 【小程序分享篇 二 】web在线踢人小程序,维持用户只能在一个台电脑持登录状态

    最近离职了, 突然记起来还一个小功能没做, 想想也挺简单,留下代码和思路给同事做个参考. 换工作心里挺忐忑, 对未来也充满了憧憬与担忧.(虽然已是老人, 换了N次工作了,但每次心里都和忐忑). 写写代 ...

  9. 前端开发中SEO的十二条总结

    一. 合理使用title, description, keywords二. 合理使用h1 - h6, h1标签的权重很高, 注意使用频率三. 列表代码使用ul, 重要文字使用strong标签四. 图片 ...

  10. 【疯狂造轮子-iOS】JSON转Model系列之二

    [疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...

随机推荐

  1. Day17_99_IO_FileReader文件字符输入流

    FileReader文件字符输入流 * 继承结构 Java.lang.Object - java.io.Reader; 抽象类 java.io.InputStreamReader; <转换流: ...

  2. Day13_68_中止线程

    中止线程方法一 * 在线程类中定义一个bollean类型的变量,默认值设置为ture,如果想要中断线程,只需要将该boolean类型的变量设置为false就可以了 * 代码 package com.s ...

  3. DPAPI机制学习

    0x00 前言 ​绝大多数应用程序都有数据加密保护的需求,存储和保护私密信息最安全的方式就是每次需要加密或解密时都从用户那里得到密码,使用后再丢弃.这种方式每次处理信息时都需要用户输入口令,对于绝大多 ...

  4. 在kubernetes上部署zookeeper,kafka集群

    本文采用网上镜像:mirrorgooglecontainers/kubernetes-zookeeper:1.0-3.4.10 准备共享存储:nfs,glusterfs,seaweed或其他,并在no ...

  5. 7.bug生命周期

    new:测试发现并提交bug,状态为new/active; open: 分配bug到开发人员,状态为open: fixed:开发人员处理完bug,将状态改为fixed: closed/reopen:测 ...

  6. 2020北航OO第一单元总结

    前言 学习面向对象这门课程的后的第一单元作业,主线是多项式求导,三次作业层层推进,由单一的幂函数求导,到幂函数和三角函数的复合求导,最后再到两种函数的嵌套求导,由两个类到重构后的十几个类,我逐渐对面向 ...

  7. 996. Number of Squareful Arrays

    Given an array A of non-negative integers, the array is squareful if for every pair of adjacent elem ...

  8. 1.Java开发环境搭建

    Java开发环境搭建 date: 2021-4-7 19:17:30 JDK安装 下载所需的JDK版本,点此下载JDK8的安装包 挑选对应的系统版本 配置环境变量 打开高级系统设置,找到系统变量 在系 ...

  9. LA3902网络

    题意:      给你一棵树,所有叶子节点都是客户端,其他的都是服务器,然后问你最少在多少个服务器上安装VOD能使所有的客户端都能流畅的看视频,流畅看视频的条件是每个客户端距离他最近的安装VOD的服务 ...

  10. Python模块化编程

    目录 模块化 自定义模块 模块的内置属性 导入模块 安装第三方模块 查看模块的属性和方法 模块化 在Python中,一个.py文件就称之为一个模块(Module),为了避免模块名冲突,Python又引 ...