SpringBoot Admin (二)计划任务增强

SpringBoot Admin
placeholder image
admin 发布于:2023-01-28 22:08:31
阅读:loading

背景介绍

前面一篇在介绍了SpringBoot Admin的基本介绍和配置集成后,本篇对于计划任务做一个小小的增强。在介绍之前我们先看下图,展示了系统内的所有的计划(定时)任务列表,分为两列分别是类方法的限定路径和定时触发策略的表达式,不难看出该列表没有对定时任务的说明或描述做实现,若系统存在几十上百的定时任务时,基本上很难知晓各个定时任务的具体含义,除非方法的名称定义成中文(这么干能行,但合适吗,科学吗),图片如下:

本次增强的实现在于对源代码的简单分析后,尝试修改的结果。实现方式通过对SpringBoot的定时任务函数增加自定义注解声明注解的含义,且通过反射拿到注解的数据并将数据追加至列表展示的属性中,所以增强后的列表展示效果如下图所示:

image.png

image

代码参考

package cn.chendd.task;

import ...;

/**
 * SpringBoot Admin 计划任务增强
 *
 * @author chendd
 * @date 2023/1/28 17:50
 */
@Component
@Aspect
public class TaskDescriptionAop {

    /**
     * 拦截规则:仅ScheduledTasksEndpoint.scheduledTasks方法
     */
    @Pointcut("execution(* org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.scheduledTasks())")
    public void pointcutDeclare(){}

    @Around(value = "pointcutDeclare()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        ScheduledTasksEndpoint.ScheduledTasksReport returnValue = (ScheduledTasksEndpoint.ScheduledTasksReport) point.proceed();
        List<ScheduledTasksEndpoint.TaskDescription> cronTasks = returnValue.getCron();
        if (cronTasks == null || cronTasks.isEmpty()) {
            return returnValue;
        }
        //只处理Cron这一种表达式
        for (ScheduledTasksEndpoint.TaskDescription cronTask : cronTasks) {
            ScheduledTasksEndpoint.RunnableDescription runnableDescription = cronTask.getRunnable();
            String target = this.getDescription(runnableDescription.getTarget());
            FieldUtils.writeDeclaredField(runnableDescription , "target" , target , true);
        }
        return returnValue;
    }

    /**
     * 重载路径,target格式为:包路径.类名称.方法名称
     * Fixme target的参数值并不是所有的都满足格式,可见源码
     * @since RunnableDescription.RunnableDescription
     * @param target 路径
     * @return 重载后的路径
     */
    public String getDescription(String target) {
        try {
            String className = FilenameUtils.getBaseName(target);
            Class clazz = ClassUtils.getClass(className);
            String methodName = FilenameUtils.getExtension(target);
            Method method = MethodUtils.getAccessibleMethod(clazz , methodName);
            if (method.isAnnotationPresent(TaskDescription.class)) {
                return String.format("%s#%s" , target , method.getAnnotation(TaskDescription.class).value());
            }
        } catch (Exception ignore) {}
        return target;
    }

}

特别说明

(1)从分析源码到改写完成不超过3小时,且未经过实践检验,请勿直接拿来注意去用于生产环境;

(2)对于SpringBoot Admin的自带功能代码未作修改,只是通过Aop拦截计划任务的列表获取方法,改写返回值的结果,源码中的代码写的滴水不漏,构造方法定义为private,属性字段只读增加有final且无setter函数,所以只能通过反射私有属性字段完成(我也很无奈);

(3)项目工程源码见:https://gitee.com/88911006/chendd-spring-cloud/tree/master/admin


 点赞


 发表评论

当前回复:作者

 评论列表


留言区