zoukankan      html  css  js  c++  java
  • [技术博客] SPRINGBOOT自定义注解

    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秒内再次刷新页面会被拦截掉,也就是不会出现重复提交表单的情况了。如下图所示。

  • 相关阅读:
    【转载】最常见的数据类型映射列表
    【自然框架 NatureFramework】 项目结构、命名空间和命名规范
    【自然框架之SSO】实现SSO的一个初步想法
    两张图说明三层的奥义!
    Android中文API(146) —— Display
    [视频监控][海康威视]二次开发 网友文章转载贴
    Android中文API(141) —— GridLayout
    Android支持横行滚动的ListView控件
    Android应用开发提高系列(5)——Android动态加载(下)——加载已安装APK中的类和资源
    [WinForm]DataGridView通过代码新增行问题
  • 原文地址:https://www.cnblogs.com/mizhiniurou/p/10890951.html
Copyright © 2011-2022 走看看