• 十分钟就能写个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

    后记

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

  • 相关阅读:
    linux study01
    复习Day10:哈希表part03:41. 缺失的第一个正数、138. 随机链表的复制
    el-select数据量过大引发卡顿,怎么办?
    【ElasticSearch】大数据量情况下的前缀、中缀实时搜索方案
    SpringCloud总结
    java实现十大排序算法
    Spring MVC:视图与视图解析器
    Typescript-----面试题
    SpringBoot整合七牛云实现图片的上传管理
    【CSS动效实战(纯CSS与JS动效)】03 精美手风琴侧边栏完整示例教程 示例1
  • 原文地址:https://blog.csdn.net/Baisitao_/article/details/126591176