zoukankan      html  css  js  c++  java
  • 自定义注解及写一个自定义注解防止数据重复提交

      关于注解的定义,使用等就不说了,在这里直接上干货,自定义注解相关的东西。

    元注解的作用就是注解其他注解,一般我们使用自定义注解时,就需要用元注解来标注我们自己的注解,一共有四个元注解

    元注解:

    java.lang.annotation提供了四种元注解,专门注解其他的注解(在自定义注解的时候,需要使用到元注解):
       @Documented –注解是否将包含在JavaDoc中
       @Retention –什么时候使用该注解
       @Target –注解用于什么地方
       @Inherited – 是否允许子类继承该注解

      1.)@Retention– 定义该注解的生命周期
      ●   RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
      ●   RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式
      ●   RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。

      2.)Target – 表示该注解用于什么地方。默认值为任何元素,表示该注解用于什么地方。可用的ElementType参数包括
      ● ElementType.CONSTRUCTOR:用于描述构造器
      ● ElementType.FIELD:成员变量、对象、属性(包括enum实例)
      ● ElementType.LOCAL_VARIABLE:用于描述局部变量
      ● ElementType.METHOD:用于描述方法
      ● ElementType.PACKAGE:用于描述包
      ● ElementType.PARAMETER:用于描述参数
      ● ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明

     3.)@Documented–一个简单的Annotations标记注解,表示是否将注解信息添加在java文档中。

     4.)@Inherited – 定义该注释和子类的关系
         @Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

    自定义注解格式:

      public @interface 注解名 {定义体}

      1. Annotation型定义为@interface, 所有的Annotation会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口.
      2. 参数成员只能用public或默认(default)这两个访问权修饰
      3. 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组.
      4. 要获取类方法和字段的注解信息,必须通过Java的反射技术来获取 Annotation对象,因为你除此之外没有别的获取注解对象的方法
      5. 注解也可以没有定义成员,

    因业务需要,为了放置表单数据重复提交,比如转账,误操作点了两下,这时候给出一个操作频繁的提示,那么我们可以写一个注解,在需要防止重复提交的地方添加上注解就ok了。代码如下:

    自定义一个注解

    1 @Target(ElementType.METHOD)
    2 @Retention(RetentionPolicy.RUNTIME)
    3 @Documented
    4 public @interface AvoidRepeatableCommit {
    5     
    6     long timeout() default 5;
    7 }

    切面:

     1 @Aspect
     2 @Component
     3 public class VoidRepeatCommitAspectJ {
     4     
     5     Logger logger = LoggerFactory.getLogger(this.getClass());
     6     @Autowired
     7     @Qualifier("redisTemplate2")
     8     private RedisTemplate<String, Object> template;
     9 
    10     @Pointcut("@annotation(com.topband.beings.aop.AvoidRepeatableCommit)")
    11     public void cutPoint(){}
    12     @Around("cutPoint()")
    13     public Object around(ProceedingJoinPoint point) throws Throwable{
    14         logger.info("around point : {}",point);
    15         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
    16         String ip = ServletUtils.getIpAddr();
    17         String token = request.getHeader(SystemConstants.TOKEN_HEADER);
    18         logger.info("ip:{};token:{}",ip,token);
    19         //获取注解
    20         MethodSignature signature = (MethodSignature) point.getSignature();
    21         Method method = signature.getMethod();
    22         //目标类、方法
    23         String className = method.getDeclaringClass().getName();
    24         String methodName = method.getName();
    25         AvoidRepeatableCommit avoidRepeatableCommit =  method.getAnnotation(AvoidRepeatableCommit.class);
    26         long timeout = avoidRepeatableCommit.timeout();
    27         if (timeout < 0){
    28             timeout = 5;
    29         }
    30         String key =SystemConstants.TOKEN_CACHE_PREFIX + token + "-" + className + "-" + methodName;
    31         logger.info("key:{};          template:{}",key,template);
    32         Object obj = template.opsForValue().get(key);
    33         logger.info("obj:{}",obj);
    34         String str = null;
    35         if(obj==null){
    36             ;
    37         }else{
    38             str = (String) template.opsForValue().get(key);
    39             logger.info("str:{}",str);
    40         }
    41 //        String str = redisUtil.get(key);
    42         //查询redis 中是否存在此key 无则添加,有则抛出异常
    43         if (StringUtil.isEmpty(str)){
    44             String value = token + "-" + className + "-" + methodName;
    45             template.opsForValue().set(key, value, 5,TimeUnit.SECONDS);
    46             return point.proceed();
    47         }else {
    48             ResponseObj response = new ResponseObj();
    49             response.setStatus(Defined.STATUS_ERROR);
    50             response.setMessage("操作过于频繁");
    51             return response;
    52         }
    53     }
    54 }

    然后在需要防止重复提交的地方,加上注解就可以了。

  • 相关阅读:
    zabbix-钉钉报警媒介
    UltraISO做U盘启动盘教程
    Oracle中的Spool缓冲池技术可以实现Oracle导出txt格式文件
    将Oracle数据库导出为txt格式
    2016技术发展趋势
    SVN分支和映射总结和数据库初步使用
    netty -- helloword
    eclipse 操作
    ftp 文件上传 下载
    redis 集群+主从同步
  • 原文地址:https://www.cnblogs.com/xiaoyao-001/p/11262443.html
Copyright © 2011-2022 走看看