SPRINGBOOT自定义注解

在springboot中,有各种各样的注解,这些注解能够简化我们的配置,提高开发效率。一般来说,springboot提供的注解已经佷丰富了,但如果我们想针对某个特定情景来添加注解,就可以使用自定义注解。

自定义注解的步骤

实现这个自定义注解一般主要有以下几个步骤。

  • maven导入相关的依赖
  • 声明注解
  • 注解的具体实现
  • 使用注解的实例

在phyweb项目中的应用

之所以会想到这个自定义注解,是因为我们在给用户发送邮件这个模块中,用户如果提交了请求,提交按钮被禁用,这个时候用户如果刷新页面的话,这仍然是一条post请求,而后面的这条请求我们不应该处理,而是提醒用户已经发送了。

  • 引入相关依赖
	 <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency> <dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
</dependency>
  • 声明自定义注解
	@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface LocalLock {
String key() default "";
int expire() default 5;
}
  • 注解实现
	@Aspect
@Configuration
public class LockMethodInterceptor { private static final Cache<String, Object> CACHES = CacheBuilder.newBuilder()
// 最大缓存 100 个
.maximumSize(1000)
// 设置写缓存后 60 秒钟过期
.expireAfterWrite(60, TimeUnit.SECONDS)
.build(); @Around("execution(public * *(..)) && @annotation(com.buaabetatwo.phyweb.annotation.LocalLock)")
public Object interceptor(ProceedingJoinPoint pjp) {
myToken = 1;
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
LocalLock localLock = method.getAnnotation(LocalLock.class);
String key = getKey(localLock.key(), pjp.getArgs());
if (!StringUtils.isEmpty(key)) {
if (CACHES.getIfPresent(key) != null) {
myToken = 0;
// throw new RuntimeException("请勿重复请求");
}
// 如果是第一次请求,就将 key 当前对象压入缓存中
CACHES.put(key, key);
} try {
return pjp.proceed();
} catch (Throwable throwable) {
throw new RuntimeException("服务器异常");
} finally {
// CACHES.invalidate(key)
}
} private String getKey(String keyExpress, Object[] args) {
for (int i = 0; i < args.length; i++) {
keyExpress = keyExpress.replace("arg[" + i + "]", args[i].toString());
}
return keyExpress;
}
  • 使用注解
	@LocalLock(key = "myToken")  //
@PostMapping("/reset-email")
public String postResetEmail(String email, Model model) {
}

经过以上四个步骤,我们的自定义注解LocalLock就大功告成了,当用户打开密码找回页面,输入邮箱后,60秒内再次刷新页面会被拦截掉,也就是不会出现重复提交表单的情况了。如下图所示。

[技术博客] SPRINGBOOT自定义注解的更多相关文章

  1. [技术博客] Springboot的Controller类使用

    Springboot的Controller类使用 @Controller:处理http请求. 代码: @Controller public class QuestionController { ... ...

  2. ******IT公司面试题汇总+优秀技术博客汇总

    滴滴面试题:滴滴打车数据库如何拆分 前端时间去滴滴面试,有一道题目是这样的,滴滴每天有100万的订单,如果让你去设计数据库,你会怎么去设计? 当时我的想法是根据用户id的最后一位对某个特殊的值取%操作 ...

  3. 创建GitHub技术博客

    创建GitHub技术博客全攻略 githubio技术博客网站生成 说明: 首先,你需要注册一个 github 账号,最好取一个有意义的名字,比如姓名全拼,昵称全拼,如果被占用,可以加上有意义的数字.本 ...

  4. 【新版】Android技术博客精华汇总

    [新版]Android技术博客精华汇总(原文链接内持续更新) http://www.apkbus.com/thread-313856-1-1.html Kotlin Kotlin学习资料汇总 http ...

  5. 创建GitHub技术博客全攻略【转】

    本文转载自:http://blog.csdn.net/renfufei/article/details/37725057/ 说明: 首先,你需要注册一个 github 账号,最好取一个有意义的名字,比 ...

  6. 技术人如何利用 github+Jekyll ,搭建一个独立免费的技术博客

    上次有人留言说,技术博客是程序员的标配,但据我所知绝大部分技术同学到现在仍然没有自己的技术博客.原因有很多,有的是懒的写,有的是怕写不好,还有的是一直想憋个大招,幻想做到完美再发出来,结果一直胎死腹中 ...

  7. [技术博客]nginx 部署 apt 源

    [技术博客] nginx 部署 apt 源 出于各种各样的原因, 有时需要自己配置apt源, 比如发布自己编写的debian软件包, 内网中只有一台电脑可以访问外网,或者在本地配置自己的apt源.我们 ...

  8. [技术博客]Android 开发 Bug Log

    [技术博客] Android 开发 Bug Log 大大小小的bug,聪明的愚蠢的都有, 持续记录中...... java.lang.IllegalArgumentException: The sty ...

  9. 【软工】[技术博客] 用Monaco Editor打造接近vscode体验的浏览器IDE

    [技术博客] 用Monaco Editor打造接近vscode体验的浏览器IDE 官方文档与重要参考资料 官方demo 官方API调用样例 Playground 官方API Doc,但其搜索框不支持模 ...

随机推荐

  1. Texture(ASDK)、ComponentKit、LayoutKit、YogaKit

    YogaKit 最轻量,改动量最小,目的最纯粹,同时也最类似于使用 frame ,需要自己造一波在 UITableView 中使用的轮子(各类 frame 结果缓存方案).同类的备选方案是 FlexB ...

  2. 8.Javascript-map、reduce、filter 等高阶函数

    高阶函数 高阶函数是对其他函数进行操作的函数,可以将它们作为参数或通过返回它们.简单来说,高阶函数是一个函数,它接收函数作为参数或将函数作为输出返回. 例如Array.prototype.map,Ar ...

  3. java InputStream的使用

    package cn.kongxh.io3;import java.io.File ;import java.io.InputStream ;import java.io.FileInputStrea ...

  4. 文章中左下角的妹子live2d看板娘

    关键词: live2d看板娘 自行搜索即可 攻略很多

  5. 使用Kubeadm安装Kubernetes【单Master节点】

    参考:Kubernetes官方文档 Kubernetes安装方案选择    Centos 7 配置科学上网 安装Calico网络插件 kubernetes-dashboard部署 Kubernetes ...

  6. Linux service进程管理

    Linux进程基本介绍: 1)在Linux中,每个执行的程序(代码)都称为一个进程.每一个进程都分配一个ID号. 2)每一个进程,都对应一个父进程,而这个父进程可以复制多个子进程.例如www服务器. ...

  7. Socket网络编程-UDP编程

    Socket网络编程-UDP编程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.UDP编程概述 1>.UDP服务端编程流程 创建socket对象.socket.SOCK_ ...

  8. css3动画 2D 3D transfrom

    2D transform 例如transform: translate(1px,30px); translate() 方法 translate()方法,根据左(X轴)和顶部(Y轴)位置给定的参数,从当 ...

  9. 类型转换的时候,.valueOf()和.parseX(),.Xvalue()的区别

    .valueOf()返回的是包装类(Wrapper Class)中的一些类型:而.parseX()返回的是基本数据类型,如int,char,double等.其参数应该是String类型. .Xvalu ...

  10. sublime设置代码缩进

    打开sublime的首选项(Preferences)下的设置-用户(Setting-User) ,配置如下代码 , "translate_tabs_to_spaces": true ...