jdk8环境下,添加重复注解的美好体验
为了实现业务层缓存,定义了几个注解:@Cache.able、@Cache.put、@Cache.del
分别实现对业务方法的 缓存检测、缓存插入 和 缓存清除。
public @interface Cache { /**
* 缓存检测
* @author netwild
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public static @interface able{ String cache() default ""; String key() default ""; } /**
* 缓存插入
* @author netwild
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public static @interface put{ String cache() default ""; String key() default ""; } /**
* 缓存清除
* @author netwild
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public static @interface del{ String cache() default ""; String key() default "" } }
对一个业务方法来说,前两个注解没必要添加多个,但 缓存清除 的注解在有些时候需要多次引用,比如:
@Override
@Cache.del(key="#(id)")
@Cache.del(key="ItemMap")
public boolean deleteById(String id) {
return super.deleteById(id);
}
以上的业务方法很简单,就是根据ID删除指定的Model
但对于缓存来说,不仅要清除相应Key值的单条数据,还要清除包含这个Model的集合数据
所以就需要为这个业务方法添加两个 @Cache.del 注解来实现上面的需求
但此时会发现IDE的错误提示:
Duplicate annotation of non-repeatable type @Cache.del.
Only annotation types marked @Repeatable can be used multiple times at one target.
我的环境是JDK8,支持重复注解就是JDK8的一个新特性,下面就来试验一下
按照提示,给 @Cache.del 增加 @Repeatable 子注解,同时创建一个包含 @Cache.del 的容器注解:
/**
* 缓存清除
* @author netwild
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
@Repeatable(Cache.dels.class) //支持重复注解,同时指定容器注解
public static @interface del{ String cache() default ""; String key() default "" } /**
* 缓存清除容器
* @author netwild
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public static @interface dels{ Cache.del[] value(); } //容器内定义指定类型的数组
代码中的红色部分是需要特殊注意的
其中对于原有的 @Cache.del 增加了 @Repeatable 子注解,说明该注解可以重复使用,同时指定了重复注解的 数据保存容器
之后增加的 @Cache.dels 就是容器注解,只在获取注解数据时使用,平时这个注解属于隐身状态
上面的修改完成之后,会发现之前在业务方法上添加的重复注解不再提示错误了,OK
最后看看如何获取重复注解的数据:
Annotation[] annos = method.getAnnotations();
if(annos.length > 0){
Arrays.stream(annos).forEach(anno -> {
if(anno instanceof Cache.del){ //单条清除注解
Cache.del temp = (Cache.del)anno;
String cacheName = buildCacheName(temp.cache());
String cacheKey = buildCacheKey(temp.key());
//具体处理逻辑
}else if(anno instanceof Cache.dels){ //多条清除注解
Cache.dels dels = (Cache.dels)anno;
Cache.del[] delarr = dels.value();
Arrays.stream(delarr).forEach(temp -> {
String cacheName = temp.cache();
String cacheKey = temp.key();
//具体处理逻辑
}
}
});
}
在遍历注解时,需要同时判断单条注解和重复注解两种情况
如果业务方法只添加了一个@Cache.del注解,那么不会执行注解容器;否则需要从容器中获得重复注解的数据
看到最后,我们才发现,JDK8对于重复注解的实现其实就是个语法糖,内部实现还是注解嵌套的模式
但在开发体验上确实比以前好多了!
jdk8环境下,添加重复注解的美好体验的更多相关文章
- JDK8新特性之重复注解
什么是重复注解 下面是JDK8中的重复注解(java.lang.annotation.Repeatable)定义的源码. @Documented @Retention(RetentionPolicy. ...
- jdk8系列二、jdk8方法引用、重复注解、更好的类型推断、新增注解
一.方法引用 方法引用使得开发者可以直接引用现存的方法.Java类的构造方法或者实例对象.方法引用和Lambda表达式配合使用,使得java类的构造方法看起来紧凑而简洁,没有很多复杂的模板代码. 方法 ...
- 如何在SAP云平台的Cloud Foundry环境下添加新的Service(服务)
我想在SAP云平台的Cloud Foundry环境下使用MongoDB的服务,但是我在Service Marketplace上找不到这个服务. cf marketplace返回的结果也没有. 解决方案 ...
- Linux环境下添加ftp账号步骤
(1)远程登录Linux服务器所用的工具,免费开源,可以从网站上很容易就下载到. (2)打开putty,输入服务器IP,进入后按提示进入用户名和密码输入超级管理员 root,然后系统让输入密码,注意此 ...
- IDEA环境下SSM整合------注解开发
根据前一篇文章的步骤,目前项目进度应该是:核心过滤器配置完成.DispatcherServlet和ContextLoader配置完成.数据库dataSource配置完成.视图解析器配置完成.Mappe ...
- LAMP 环境下添加多个虚拟主机(网站)
Ubuntu系统 #在/var/www目录下新建两个文件夹bbs和oa,执行完以上命令后,/var/www目录下有bbs.oa三个文件夹,名称与二级域名对应,分别存放三个系统的php文件,这样便于日后 ...
- As环境下添加android support library依赖库
2015年的google大会上,google发布了新的Android Support Design库的新组件之一,以此来全面支持Material Design 设计风格的UI效果,为了可以使用这些新颖 ...
- 在MyEclipse环境下添加MySql数据库
首先最好在添加的时候,确保你的数据库处于打开状态:其次,要按照jdbc:mysql://[host:port],[host:port].../[database]把url写对:然后,需要添加mysql ...
- IIS8.5 的环境下添加配置WCF服务!!!!!
添加步骤: 1.打开iis8.5,先部署wcf服务. 2.首先添加MIME类型 扩展名:“.svc” MIME类型:“application/octet-stream” 3.添加 处理程序映射 请求路 ...
随机推荐
- Unity主线程和子线程跳转调用(2)
在上一篇介绍了多线程和Unity交互方式,但是由于我的项目是一个unity编辑器插件项目,很显然上一篇的代码需要加以修改,在编辑器下实现Loom. 1,Editor下的没有Update这个生命周期函数 ...
- async 和 await 的用法示例
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- CRC算法
https://blog.csdn.net/dream_1996/article/details/73588269
- Vue 中的 v-cloak 解读
v-cloak 的作用和用法 用法: 这个指令保持在元素上直到关联实例结束编译.和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Must ...
- 【java基础】 == 和 equals() 的区别
==号和equals()方法都是比较是否相等的方法,那它们有什么区别和联系呢? 首先,==号在比较基本数据类型(指的值类型)时比较的是值,而用==号比较两个对象时比较的是两个对象的地址值: int x ...
- java,JsonFormat格式化日期问题
今天使用以下代码格式日期字段 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; 发现这样渲 ...
- HiveSql调优经验
背景 在刚使用hive的过程中,碰到过很多问题,任务经常需要运行7,8个小时甚至更久,在此记录一下这个过程中,我的一些收获 join长尾 背景 SQL在Join执行阶段会将Join Key相同的数据分 ...
- 产品相关 做产品VS做项目
做产品VS做项目 by:授客 QQ:1033553122 相关定义 根据GB/T19000—2008<质量管理体系基础和术语>,有以下定义 过程process 一组将输入转化为输出的相互关 ...
- PSP软件开发过程
1. 引言 这是为了编写psp系统的软件需求分析,主要按照提供的相关需求和功能. 1.1 项目风险 风险承担者包括: 任务提出者:承担任务不能完全按照想象的做出,投入等: 软件开发者:可能不能按时交付 ...
- 8 tensorflow修改tensor张量矩阵的某一列
1.tensorflow的数据流图限制了它的tensor是只读属性,因此对于一个Tensor(张量)形式的矩阵,想修改特定位置的元素,比较困难. 2.我要做的是将所有的操作定义为符号形式的操作.也就是 ...