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

  • 相关阅读:
    LeetCode 93. Restore IP Addresses
    LeetCode 92. Reverse Linked List II
    LeetCode 94. Binary Tree Inorder Traversal
    javaweb中重定向和请求转发(response.sendRedirect()和request.getRequestDispatcher(rul).forward(request,response)))的区别
    java关于jdbc的配置与使用步骤
    关于php中的include html文件的问题,为什么html可以在php中执行
    yii2 无法显示debug条的问题解决方法
    elasticsearch报错expected <block end>, but found BlockMappingStart解决方法
    sysctl -p 报错问题的解决方法
    yii2 Rbac使用yii命令一键建表
  • 原文地址:https://www.cnblogs.com/mizhiniurou/p/10890951.html
Copyright © 2020-2023  润新知