为了实现业务层缓存,定义了几个注解:@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环境下,添加重复注解的美好体验的更多相关文章

  1. JDK8新特性之重复注解

    什么是重复注解 下面是JDK8中的重复注解(java.lang.annotation.Repeatable)定义的源码. @Documented @Retention(RetentionPolicy. ...

  2. jdk8系列二、jdk8方法引用、重复注解、更好的类型推断、新增注解

    一.方法引用 方法引用使得开发者可以直接引用现存的方法.Java类的构造方法或者实例对象.方法引用和Lambda表达式配合使用,使得java类的构造方法看起来紧凑而简洁,没有很多复杂的模板代码. 方法 ...

  3. 如何在SAP云平台的Cloud Foundry环境下添加新的Service(服务)

    我想在SAP云平台的Cloud Foundry环境下使用MongoDB的服务,但是我在Service Marketplace上找不到这个服务. cf marketplace返回的结果也没有. 解决方案 ...

  4. Linux环境下添加ftp账号步骤

    (1)远程登录Linux服务器所用的工具,免费开源,可以从网站上很容易就下载到. (2)打开putty,输入服务器IP,进入后按提示进入用户名和密码输入超级管理员 root,然后系统让输入密码,注意此 ...

  5. IDEA环境下SSM整合------注解开发

    根据前一篇文章的步骤,目前项目进度应该是:核心过滤器配置完成.DispatcherServlet和ContextLoader配置完成.数据库dataSource配置完成.视图解析器配置完成.Mappe ...

  6. LAMP 环境下添加多个虚拟主机(网站)

    Ubuntu系统 #在/var/www目录下新建两个文件夹bbs和oa,执行完以上命令后,/var/www目录下有bbs.oa三个文件夹,名称与二级域名对应,分别存放三个系统的php文件,这样便于日后 ...

  7. As环境下添加android support library依赖库

    2015年的google大会上,google发布了新的Android Support Design库的新组件之一,以此来全面支持Material Design 设计风格的UI效果,为了可以使用这些新颖 ...

  8. 在MyEclipse环境下添加MySql数据库

    首先最好在添加的时候,确保你的数据库处于打开状态:其次,要按照jdbc:mysql://[host:port],[host:port].../[database]把url写对:然后,需要添加mysql ...

  9. IIS8.5 的环境下添加配置WCF服务!!!!!

    添加步骤: 1.打开iis8.5,先部署wcf服务. 2.首先添加MIME类型 扩展名:“.svc” MIME类型:“application/octet-stream” 3.添加 处理程序映射 请求路 ...

随机推荐

  1. CentOS普通用户没有sudo权限

    sudo是linux系统管理指令,是允许系统管理员让普通用户执行一些或者全部的root命令的一个工具,如halt,reboot,su等等.这样不仅减少了root用户的登录 和管理时间,同样也提高了安全 ...

  2. IDEA相关设置

    今天终于放弃了MyEclipse,在使用MyEclipse中的各种心酸就不多说,总结成一句话就是:珍爱生命,远离MyEclipse. 换到IDEA后,安装了IdeaVim插件,支持vim的操作,提高的 ...

  3. ios app真正的相互!!调用

    1.需求:A应用打开B.B回跳到A   2.问题: 看到网络上的文档讲的大多数都是app单向跳转的例子,而我们在跳转到第二个app的时候往往需要返回到原来的app,虽然支付宝微信等第三方等应用会有回调 ...

  4. Java基础教程(21)--泛型

    一.为什么使用泛型   泛型意味着编写的代码可以被很多不同类型的对象所重用.例如,我们不希望为存放String和Integer对象的集合设计不同的类.现在的ArrayList类可以存放任何类型的对象, ...

  5. TCP三次握手是什么?为什么要进行三次握手?两次,四次握手可以吗?

    1.第一次握手,发送SYN报文,传达信息:“你好,我想建立连接”: 第二次握手,回传SYN+ACK报文,传达信息:“好的,可以建立链接”:    第三次握手,回传ACK报文,传到信息:“好的,我知道了 ...

  6. Storm框架:Storm整合springboot

    我们知道Storm本身是一个独立运行的分布式流式数据处理框架,Springboot也是一个独立运行的web框架.那么如何在Strom框架中集成Springboot使得我们能够在Storm开发中运用Sp ...

  7. 177. [USACO Jan07] 有限制的素数

    177. [USACO Jan07] ★   输入文件:qprime.in   输出文件:qprime.out   简单对比 时间限制:1 s   内存限制:128 MB Farmer John 开始 ...

  8. 分享一个oracle 完整备份的批处理文件

    该批处理是基本可以无限针对使用window 服务器的oracle 备份,如下: set mydate=%DATE:~0,10% exp e_cards2016/e_cards2016@orcl ful ...

  9. vue + skyline 搭建 一个开发环境

    1.之前用的是ext +  skyline搭建环境 ,正好最近是做前端的事情,有时间用vue + skyline 搭建一个三维场景 2.准备vue 2.x  ,UI 用的是iview 和element ...

  10. Flare-On4 解题复现

    01 是一个 html 页面, 用开发者工具看看,发现是简单的 js 加密. 猜测加密算法可逆,试着用 PyvragFvqrYbtvafNerRnfl@syner-ba.pbz 作为输入,然后调试 , ...