• 十分钟就能写个xxl-job插件


    前言

    有时候跑单测,需要启动spring容器,但是不想启动xxl-job,这时候就希望有个配置来让我们控制是否启动xxl-job。

    原文链接:https://blog.csdn.net/Baisitao_/article/details/126591176
    原文作者:Sicimike

    于是博主一通搜索,找到了这个issues。
    https://gitee.com/xuxueli0323/xxl-job/issues/IOFA6

    xxl-job-git
    可以看到,可能作者觉得没有提供这个配置的必要,既然官方没提供类似的配置,那就自己开发一个吧。

    环境

    • spring-boot 2.1.2 RELEASE
    • junit 4.12
    • spring-boot-starter-test 2.1.2 RELEASE
    • xxl-job-core 2.2.0

    简读源码

    简单的看了下xxl-job的源码,发现启动入口在com.xxl.job.core.executor.impl.XxlJobSpringExecutor#afterSingletonsInstantiated这里,因为博主集成了spring,所以实际上是在Spring提供的钩子函数org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated启动的xxl-job。如果没有集成spring,是在com.xxl.job.core.executor.XxlJobExecutor#start启动,下面是XxlJobSpringExecutor#afterSingletonsInstantiated的源码

    @Override
    public void afterSingletonsInstantiated() {
    
        // init JobHandler Repository
        /*initJobHandlerRepository(applicationContext);*/
    
        // init JobHandler Repository (for method)
        initJobHandlerMethodRepository(applicationContext);
    
        // refresh GlueFactory
        GlueFactory.refreshInstance(1);
    
        // super start
        try {
            super.start();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    可以看到主要做了三件事

    • 注册JobHandler
    • 刷新GlueFactory
    • 启动真正的com.xxl.job.core.executor.XxlJobExecutor

    由于作者没有预留相关的扩展点,所以只能自己想办法。大家在碰到类似场景的时候可以想想这句话。

    没有什么是包一层不能解决的

    这句话通俗易懂,实际上可以理解为代理。只要有了代理就可以为所欲为了。

    实现

    自定义类继承XxlJobSpringExecutor

    我们可以自定义类来继承XxlJobSpringExecutor,然后重写方法afterSingletonsInstantiated

    public class SicimikeXxlJobSpringExecutor extends XxlJobSpringExecutor {
    
        private static final Logger logger = LoggerFactory.getLogger(SicimikeXxlJobSpringExecutor.class);
    
        @Override
        public void afterSingletonsInstantiated() {
        	// 获取单测时设置的属性,可以自己定义属性名
        	// 不要问这个属性key怎么来的,后文单测时设置的
            String xxlJobEnable = System.getProperty("sicimike.xxjob.enable");
            if (Objects.equals(xxlJobEnable, "false")) {
            	// 如果设置了【不启动】xxljob,则直接跳过
                logger.info("xxljob disable success .");
                return;
            }
            // 如果没有设置,或者设置了启动xxljob,则调用父类的启动入口
            super.afterSingletonsInstantiated();
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    修改配置

    由于自定义类继承了XxlJobSpringExecutor,所以配置的时候需要配置自定的类,用XML方式配置的同理

    @Bean
    public XxlJobSpringExecutor xxlJobExecutor() {
    	// 注意,这里实例化的是自定义的子类
        XxlJobSpringExecutor xxlJobSpringExecutor = new SicimikeXxlJobSpringExecutor();
        // 设置属性
        // xxlJobSpringExecutor.setXxx
        return xxlJobSpringExecutor;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    单测使用

    设置好了之后,在单测类中添加如下代码即可

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class AaaServiceTest {
    
        @BeforeClass
        public static void before() {
        	// 单测不启动xxljob
        	// 注意属性key要和SicimikeXxlJobSpringExecutor中保持一致
            System.setProperty("sicimike.xxjob.enable", "false");
        }
    
        @Autowired
        private AaaService aaaService;
    
        @Test
        public void testAaa() {
            aaaService.xxxx();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    不出意外的话,启动单测会打出如下日志

    2022-08-29 20:13:02.032  INFO 32094 --- [           main] com.sicimike.SicimikeXxlJobSpringExecutor       21 : xxljob disable success .
    
    • 1

    后记

    可以看到,读源码并不是为了读而读,而是为了解决实际问题。并且并不一定需要修改源码才能达到目的,可以通过扩展的方式,这样也符合开闭原则。

  • 相关阅读:
    [附源码]Python计算机毕业设计Django毕业生就业管理系统
    腾讯罗嘉黎:基于APM的腾讯可观测平台技术与实践
    【Spring】spring中存储Bean(对象)的相关注解及相关用法
    vulhub靶场搭建与使用
    大数据-之LibrA数据库系统告警处理(ALM-12053 主机文件句柄使用率超过阈值)
    六大排序算法:插入、选择、冒泡、快排、希尔、归并
    MyBatisPlus(十八)字段类型处理器:对象存为JSON字符串
    vue2和vue3响应式的理解及如何进行依赖收集
    Vue3初体验
    服务器断电重启后报XFS文件系统错误 XFS (dm-0)_ Metadata I_O error
  • 原文地址:https://blog.csdn.net/Baisitao_/article/details/126591176