spring自定义注解的使用
前几天写了一个消息中间件(kafka)的封装,业务方发现消费者需要配置的东西太多(每增加一个topic和实现类都需要在配置文件中加,会显得很繁琐)。于是我为了尽量减少这个XML配置,采用注解的方式来获取topic和实现类。
第一步:先自定义一个注解,有一个topic的方法用于表明需要监听的topic
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
public @interface TopicSub {
TopicType topic() ;
}
第二步:获取所有使用该注解的类以及注解值
List<MessageContainer> messageContainerList= Lists.newArrayList();
Map<String, Object> maps= SpringBeanUtils.getAnnotation(TopicSub.class);
for (Map.Entry<String, Object> entry : maps.entrySet()) {
TopicSub topicAnn = entry.getValue().getClass().getAnnotation(TopicSub.class);
MessageContainer messageContainer=new MessageContainer(topicAnn.topic().getName());
messageContainer.setMessageHandle((MessageListener)entry.getValue());
messageContainerList.add(messageContainer);
}
特别说明:SpringBeanUtils.getAnnotation(TopicSub.class)是调用ApplicationContext容器的 getBeansWithAnnotation(Class<? extends Annotation> var1)方法,返回的是所有使用该注解的bean
然后遍历这个map,拿到每个bean上的注解值(topic方法的值);这里拿bean的注解值的方式是反射.getClass().getAnnotation(),如果bean是放在被代理的包下(service包下一般都是被事务代理了,AOP的实现就是JDK(CJLIB)动态代理),那么.getClass().getAnnotation()这个方法是拿不到注解值的,因为.getClass()拿到的是代理类而不是真正的类,建议这些实现类放在一个不被代理的包下(就是建立一个普通的package即可),如果放在代理包下,那就需要先获取真正的bean,再反射。
三、监听到消息后,根据topic的值调用实现类
for (MessageContainer messageContainer : PropertyFactory.consumerProperty.getMessageContainers()) {
if (consumerRecord.topic().equals(messageContainer.getTopic())) {
try {
messageContainer.getMessageHandle().onMessage(consumerMessageBO);
}catch (KafkaComsumException e){
}
}
四、业务方实现类
@Component
@TopicSub(topic = TopicType.SMS_ASYNC_SEND)
public class SmsMessageHandler implements MessageListener{
public static final Logger log= LoggerFactory.getLogger(SmsMessageHandler.class);
@Autowired
private SmsSendLogDao smsSendLogDao;
public void onMessage(ConsumerMessageBO consumerMessageBO) throws KafkaComsumException{
log.info(JSONObject.toJSONString(consumerMessageBO));
try {
SmsMessageEO message =JSONObject.parseObject(consumerMessageBO.getMessage().toString(),SmsMessageEO.class);
for(String phone:message.getPhone() ){
SmsResult result= SmsUtils.sendSms(phone,message.getContent(),message.getProduct());
SmsSendLogDO smsSendLogDO=new SmsSendLogDO();
smsSendLogDO.setContent(message.getContent());
smsSendLogDO.setPhone(phone);
smsSendLogDO.setProduct(message.getProduct());
smsSendLogDO.setCreateTime(new Date());
smsSendLogDO.setStatus(result.getCode()==1?1:0);
smsSendLogDO.setSender(message.getSender().getName());
smsSendLogDao.insert(smsSendLogDO);
}
}catch (Exception e){
throw new KafkaComsumException();
} } }
前三步都是在jar包中完成(对业务方是透明的),业务方只需要完成第四步消息实现类的逻辑即可(不需要任何xml的配置),有没有感觉很清爽啊!
这样我们就进一步提升了中间件解耦的程度,其实也满简单的,唯一的坑就是AOP中反射获取到的是代理类这个问题,也是小伙伴们需要注意的!
spring自定义注解的使用的更多相关文章
- spring自定义注解实现登陆拦截器
1.spring自定义注解实现登陆拦截器 原理:定义一个注解和一个拦截器,拦截器拦截所有方法请求,判断该方法有没有该注解.没有,放行:有,要进行验证.从而实现方法加注解就需要验证是否登陆. 2.自定义 ...
- spring - 自定义注解
本自定义注解的作用:用于控制类方法的调用,只有拥有某个角色时才能调用. java内置注解 1.@Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括: ElemenetTy ...
- Spring 自定义注解,配置简单日志注解
java在jdk1.5中引入了注解,spring框架也正好把java注解发挥得淋漓尽致. 下面会讲解Spring中自定义注解的简单流程,其中会涉及到spring框架中的AOP(面向切面编程)相关概念. ...
- 照虎画猫写自己的Spring——自定义注解
Fairy已经实现的功能 读取XML格式配置文件,解析得到Bean 读取JSON格式配置文件,解析得到Bean 基于XML配置的依赖注入 所以,理所当然,今天该实现基于注解的依赖注入了. 基于XML配 ...
- 使用Spring自定义注解实现任务路由的方法
在Spring mvc的开发中,我们可以通过RequestMapping来配,当前方法用于处理哪一个URL的请求.同样我们现在有一个需求,有一个任务调度器,可以按照不同的任务类型路由到不同的任务执行器 ...
- 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(面向切面编程)相关概念. ...
随机推荐
- 基于centos系统安装pip模块
pip模块安装 centos 6.5安装pip,centos安装Python包管理安装工具pip的方法如下: 此安装包使用的是pip1.5.5版本 wget --no-check-certificat ...
- scala 高级编程
一.函数式编程 Scala中的函数可以独立存在, 不需要依赖任 何类和对象 def 放在类中就是方法:放在外边就是函数 1.将函数赋值给变量 Scala中的函数是一等公民, 可以独立定义, 独立存在 ...
- [JOI 2014 Final] IOI 馒头
link 试题分析 我们发现若是要选馒头的话则应该从馒头售价高的先装. 并且若要选择包装盒时应该选择装x个最小的时候.所以只需要贪心$+$背包即可. #include<iostream> ...
- [IOI2013]Dreaming
link 一道非常类似的题目(link) 试题大意 给你一棵含有$n$个节点的有边权森林,问每次连边将会用$L$的代价,问你若此图通过加边成为树时的最小直径.$n \leq 5\times 10^5$ ...
- 【CF601C】Kleofáš and the n-thlon
Portal -->CF601C Description 大概是说\(m\)个人参加\(n\)场比赛,每场一人有一个排名,每场没有两个人排名相同,一个人最后的得分是\(n\)场比赛的排名相加,现 ...
- 课程14:get和post是神马
http://www.codeschool.cn/lesson/14.html get和post是神马? get和post是http中两种最常用到的请求类型 简单理解get请求 get请求多用于获取信 ...
- SpringMVC接收复杂集合对象(参数)代码示例
原文: https://www.jb51.net/article/128233.htm SpringMVC接收复杂集合对象(参数)代码示例 更新时间:2017年11月15日 09:18:15 作者 ...
- Maven仓库--Nexus的配置使用
一.Nexus的作用 指定私服的中央地址.将自己的Maven项目指定到私服地址.从私服下载中央库的项目索引.从私服仓库下载依赖组件.将第三方项目jar上传到私服供其他项目组使用. 二.Nexus仓库 ...
- 「Django」rest_framework学习系列-API访问跨域问题
#以中间件方式解决API数据访问跨域问题1.API下新建文件夹下写PY文件a.引入内置类继承: from django.middleware.common import MiddlewareMixin ...
- Debian sudo自动补全
解决 debian sudo TAB 键不能自动补全命令的原因 一般情况,命令行输入 sudo apt-get ins 按 tab ,它后面会自动补全为 install 如果右面写了包的名的一部分,按 ...