zl程序教程

您现在的位置是:首页 >  后端

当前栏目

使用Spring自定义注解实现任务路由

Spring路由 实现 自定义 任务 注解 使用
2023-09-27 14:20:47 时间

使用Spring自定义注解实现任务路由



在Spring mvc的开发中,我们可以通过RequestMapping来配,当前方法用于处理哪一个URL的请求.同样我们现在有一个需求,有一个任务调度器,可以按照不同的任务类型路由到不同的任务执行器。其本质就是通过外部参数进行一次路由和Spring mvc做的事情类似。简单看了Spring mvc的实现原理之后,决定使用自定义注解的方式来实现以上功能。

自定义TaskHandler注解


@Target({ElementType.TYPE})  @Retention(RetentionPolicy.RUNTIME)  @Documented  @Component  public @interface TaskHandler {      String taskType() default ""; 

以上定义了任务处理器的注解,其中@Component表示在spring 启动过程中,会扫描到并且注入到容器中。taskType表示类型。

任务处理器定义



以上定义了一个任务执行的处理器,其他所有的具体的任务执行器继承实现这个方法。其中Task表示任务的定义,包括任务Id,执行任务需要的参数等。

任务处理器实现

接下来,我们可以实现一个具体的任务处理器。


@TaskHandler(taskType = "UserNameChanged")  public class UserNameChangedSender extends AbstractTaskHandler {      @Override      public BaseResult execute(Task task) {        return new BaseResult();      } 

以上我们就实现一个用户名修改通知的任务处理器,具体的业务逻辑这里没有实现。

其中:@TaskHandler(taskType = "UserNameChanged"),这里我们指定这个Handler用于处理用户名变更的任务

任务处理Handler注册



    private final static Map String, AbstractTaskHandler  TASK_HANDLERS_MAP = new HashMap ();      private static final Logger LOGGER = LoggerFactory.getLogger(TaskHandlerRegister.class);      @Override      protected void initApplicationContext(ApplicationContext context) throws BeansException {          super.initApplicationContext(context);          Map String, Object  taskBeanMap = context.getBeansWithAnnotation(TaskHandler.class);          taskBeanMap.keySet().forEach(beanName -  {              Object bean = taskBeanMap.get(beanName);              Class clazz = bean.getClass();              if (bean instanceof AbstractTaskHandler   clazz.getAnnotation(TaskHandler.class) != null) {                  TaskHandler taskHandler = (TaskHandler) clazz.getAnnotation(TaskHandler.class);                  String taskType = taskHandler.taskType();                  if (TASK_HANDLERS_MAP.keySet().contains(taskType)) {                      throw new RuntimeException("TaskType has Exits. TaskType=" + taskType);                  }                  TASK_HANDLERS_MAP.put(taskHandler.taskType(), (AbstractTaskHandler) taskBeanMap.get(beanName));                  LOGGER.info("Task Handler Register. taskType={},beanName={}", taskHandler.taskType(), beanName);              }          });      }      public static AbstractTaskHandler getTaskHandler(String taskType) {          return TASK_HANDLERS_MAP.get(taskType);      } 

这里继承了Spring的ApplicationObjectSupport类,具体的注册过程如下

Spring完成bean的初始化 查找spring的容器中,所有带有TaskHandler注解的bean 校验bean是否为AbstractTaskHandler类型,获取到taskType 把该bean放到TASK_HANDLERS_MAP容器中,即注册完成

任务执行

接下来我们来看下任务执行



        String taskType=task.getTaskType();          if (TaskHandlerRegister.getTaskHandler(taskType) == null) {              throw new RuntimeException("cant find taskHandler,taskType=" + taskType);          }          AbstractTaskHandler abstractHandler = TaskHandlerRegister.getTaskHandler(taskType);          return abstractHandler.execute(task);      } 

这里发起任务执行的是一个Job,具体过程如下

校验该任务类型,有没有在注册中心注册相关Handler 从任务注册中心获取到对应的处理的Handelr 执行该Handelr

以上过程就完成了,可以实现基于注解的一个任务路由过程。其实现思路来自于Spring mvc的RequestMapping的设计思路.


作者:wangyan9110

来源:51CTO


Spring 创建一个自定义注解 平时在用springBoot的使用,常常会用到@Service,@Compent等等注解,简化了我们的开发流程,提升了开发效率.那如何自己来写一个注解呢?下面就来介绍一下。
Spring Boot源码学习:自动配置与自定义注解详解 @RestContrller :此注解标记的类下的 所有 方法均会返回一个 domain 对象以代替视图@Controller、@ResponseBody 的缩写使用 Jackson2 以及 MappingJackson2HttpMessageConverter 类自动转换对象为 JSON @SpringBootApplication:快捷注释,包含以下内容@Configuration:将该类标记为上下文 bean 对象的源@EnableAutoConfiguration:@ComponentScan
通过源码理解Spring中@Scheduled的实现原理并且实现调度任务动态装载(下) 最近的新项目和数据同步相关,有定时调度的需求。之前一直有使用过Quartz、XXL-Job、Easy Scheduler等调度框架,后来越发觉得这些框架太重量级了,于是想到了Spring内置的Scheduling模块。而原生的Scheduling模块只是内存态的调度模块,不支持任务的持久化或者配置(配置任务通过@Scheduled注解进行硬编码,不能抽离到类之外),因此考虑理解Scheduling模块的底层原理,并且基于此造一个简单的轮子,使之支持调度任务配置:通过配置文件或者JDBC数据源。
通过源码理解Spring中@Scheduled的实现原理并且实现调度任务动态装载(上) 最近的新项目和数据同步相关,有定时调度的需求。之前一直有使用过Quartz、XXL-Job、Easy Scheduler等调度框架,后来越发觉得这些框架太重量级了,于是想到了Spring内置的Scheduling模块。而原生的Scheduling模块只是内存态的调度模块,不支持任务的持久化或者配置(配置任务通过@Scheduled注解进行硬编码,不能抽离到类之外),因此考虑理解Scheduling模块的底层原理,并且基于此造一个简单的轮子,使之支持调度任务配置:通过配置文件或者JDBC数据源。
Spring Boot 定时任务,怎么实现任务动态增删启停? 在spring boot项目中,可以通过@EnableScheduling注解和@Scheduled注解实现定时任务,也可以通过SchedulingConfigurer接口来实现定时任务。但是这两种方式不能动态添加、删除、启动、停止任务。要实现动态增删启停定时任务功能,比较广泛的做法是集成Quartz框架。
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载