使用Spring自定义注解实现任务路由的方法
在Spring mvc的开发中,我们可以通过RequestMapping来配,当前方法用于处理哪一个URL的请求.同样我们现在有一个需求,有一个任务调度器,可以按照不同的任务类型路由到不同的任务执行器。其本质就是通过外部参数进行一次路由和Spring mvc做的事情类似。简单看了Spring mvc的实现原理之后,决定使用自定义注解的方式来实现以上功能。
自定义TaskHandler注解
|
1
2
3
4
5
6
7
8
|
@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface TaskHandler { String taskType() default "";} |
以上定义了任务处理器的注解,其中@Component表示在spring 启动过程中,会扫描到并且注入到容器中。taskType表示类型。
任务处理器定义
|
1
2
3
4
5
6
7
8
9
10
|
public abstract class AbstractTaskHandler { /** * 任务执行器 * * @param task 任务 * @return 执行结果 */ public abstract BaseResult execute(Task task);} |
以上定义了一个任务执行的处理器,其他所有的具体的任务执行器继承实现这个方法。其中Task表示任务的定义,包括任务Id,执行任务需要的参数等。
任务处理器实现
接下来,我们可以实现一个具体的任务处理器。
|
1
2
3
4
5
6
7
|
@TaskHandler(taskType = "UserNameChanged")public class UserNameChangedSender extends AbstractTaskHandler { @Override public BaseResult execute(Task task) { return new BaseResult(); }} |
以上我们就实现一个用户名修改通知的任务处理器,具体的业务逻辑这里没有实现。
其中:@TaskHandler(taskType = "UserNameChanged"),这里我们指定这个Handler用于处理用户名变更的任务
任务处理Handler注册
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
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类,具体的注册过程如下
- Spring完成bean的初始化
- 查找spring的容器中,所有带有TaskHandler注解的bean
- 校验bean是否为AbstractTaskHandler类型,获取到taskType
- 把该bean放到TASK_HANDLERS_MAP容器中,即注册完成
任务执行
接下来我们来看下任务执行
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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,具体过程如下
- 校验该任务类型,有没有在注册中心注册相关Handler
- 从任务注册中心获取到对应的处理的Handelr
- 执行该Handelr
以上过程就完成了,可以实现基于注解的一个任务路由过程。其实现思路来自于Spring mvc的RequestMapping的设计思路
使用Spring自定义注解实现任务路由的方法的更多相关文章
- spring - 自定义注解
本自定义注解的作用:用于控制类方法的调用,只有拥有某个角色时才能调用. java内置注解 1.@Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括: ElemenetTy ...
- spring自定义注解实现登陆拦截器
1.spring自定义注解实现登陆拦截器 原理:定义一个注解和一个拦截器,拦截器拦截所有方法请求,判断该方法有没有该注解.没有,放行:有,要进行验证.从而实现方法加注解就需要验证是否登陆. 2.自定义 ...
- Spring 自定义注解,配置简单日志注解
java在jdk1.5中引入了注解,spring框架也正好把java注解发挥得淋漓尽致. 下面会讲解Spring中自定义注解的简单流程,其中会涉及到spring框架中的AOP(面向切面编程)相关概念. ...
- 照虎画猫写自己的Spring——自定义注解
Fairy已经实现的功能 读取XML格式配置文件,解析得到Bean 读取JSON格式配置文件,解析得到Bean 基于XML配置的依赖注入 所以,理所当然,今天该实现基于注解的依赖注入了. 基于XML配 ...
- Spring自定义注解扫描的实现
目标:实现自定义spring自动扫描注解.主要为后期实现分布式服务框架自动注解提供技术支持 技术分析:通过配置组件扫描标签使spring解析标签. 1. JewelScanBeanDefaultPar ...
- 2018-02-11 发布 spring 自定义注解(annotation)与 aop获取注解
知识点: Java自定义注解.spring aop @aspect的使用 首先我们先介绍Java自定义注解. 在开发过程中,我们实现接口的时候,会出现@Override,有时还会提示写@Suppres ...
- 深入Spring:自定义注解加载和使用
前言 在工作中经常使用Spring的相关框架,免不了去看一下Spring的实现方法,了解一下Spring内部的处理逻辑.特别是开发Web应用时,我们会频繁的定义@Controller,@Service ...
- 【转】spring 自定义注解(annotation)与 aop获取注解
首先我们先介绍Java自定义注解. 在开发过程中,我们实现接口的时候,会出现@Override,有时还会提示写@SuppressWarnings.其实这个就是Java特有的特性,注解. 注解就是某种注 ...
- Spring 自定义注解,结合AOP,配置简单日志注解 (转)
java在jdk1.5中引入了注解,spring框架也正好把java注解发挥得淋漓尽致. 下面会讲解Spring中自定义注解的简单流程,其中会涉及到spring框架中的AOP(面向切面编程)相关概念. ...
随机推荐
- JavaScript编程题(含腾讯2016校招题)
作者:ManfredHu 链接:http://www.manfredhu.com/2016/04/02/15-veryGoodForUsing/ 声明:版权所有,转载请保留本段信息,否则请不要转载 几 ...
- PhoneGap原理
http://www.oschina.net/question/213217_46380
- S11 day 94 RestFramework 之 APIView视图
VIEW视图(Django自带的) 1. url url(r'login/$', views.login.as_view()), 2.点开 as_view() , as_view()为类方法. l ...
- CentOS 6 - 升级内核
有的时候,需要升级Linux内核,今天我就是在CentOS 6中升级内核,在没有升级内核之前,我的CentOS 6只有2.6.32这一个内核,也是默认启动的内核.下面就开始一步步操作升级内核了! 一, ...
- 攻防组网之—-VMware路由器安装设置
本文作者:i春秋作家——红发香克斯 前言 VMWare功能很强大,我一直有个想法是能不能用一台高配的主机利用VM虚拟化出一个或多个真实的子网,或者子网里面还有子网,其中使用VM自动的功能可以实现多个网 ...
- [JavaScript] iframe加载完成事件
//iframe加载完成后,对其子元素进行操作 var iframe = document.getElementById("re-img"); if (iframe.attachE ...
- VSCode保存插件配置并使用 gist 管理代码片段
setting sync 保存配置 由于公司和家里都使用 VSCode 作为主要编辑器,同步配置是最紧要的.VSCode 提供了setting sync插件,很方便我们同步插件配置.引用网上教程: 在 ...
- SSH免密码远程登录Linux
1. 有A,B两台机(Linux/unix), 要想从A用ssh远程登录到B上(假设各自的IP,A:192.168.100:B:192.168.1.104). 2. 在A机上,用“ssh-keygen ...
- LODOP内嵌挡住浏览器的div弹出层
首先,做一个简单的div弹出层用于测试,该弹出层的介绍可查看本博客另一篇博文:[JS新手教程]浏览器弹出div层 然后加入LODOP内嵌,LODOP可以内嵌,C-LODOP不能内嵌,可以在IE等浏览器 ...
- 放弃jQuery,使用原生js吧!
转自:http://itakeo.com/blog/2015/07/28/nojq/ 随着IE6.7.8的逐渐淘汰,HTML5的兴起,以及侧重点放在了移动端,jQuery可能变的不在那么重要,原生一样 ...