当前位置: 移动技术网 > IT编程>开发语言>Java > 使用Spring自定义注解实现任务路由的方法

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

蜜蜂采蜜,div css视频教程,娇宠的条件

在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表示类型。

任务处理器定义

public abstract class abstracttaskhandler {

  /**
   * 任务执行器
   *
   * @param task 任务
   * @return 执行结果
   */
   public abstract baseresult execute(task task);
}

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

任务处理器实现

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

@taskhandler(tasktype = "usernamechanged")
public class usernamechangedsender extends abstracttaskhandler {
  @override
  public baseresult execute(task task) {
   return new baseresult();
  }
}

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

其中:@taskhandler(tasktype = "usernamechanged"),这里我们指定这个handler用于处理用户名变更的任务

任务处理handler注册

public class taskhandlerregister extends applicationobjectsupport {

  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类,具体的注册过程如下

  1. spring完成bean的初始化
  2. 查找spring的容器中,所有带有taskhandler注解的bean
  3. 校验bean是否为abstracttaskhandler类型,获取到tasktype
  4. 把该bean放到task_handlers_map容器中,即注册完成

任务执行

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

public class taskexecutor implements job {

  private static final string task_type = "tasktype";

  @override
  public baseresult execute(task task){
    string tasktype=task.gettasktype();
    if (taskhandlerregister.gettaskhandler(tasktype) == null) {
      throw new runtimeexception("can't find taskhandler,tasktype=" + tasktype);
    }
    abstracttaskhandler abstracthandler = taskhandlerregister.gettaskhandler(tasktype);
    return abstracthandler.execute(task);
  }
}

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

  1. 校验该任务类型,有没有在注册中心注册相关handler
  2. 从任务注册中心获取到对应的处理的handelr
  3. 执行该handelr

以上过程就完成了,可以实现基于注解的一个任务路由过程。其实现思路来自于spring mvc的requestmapping的设计思路.希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网