likes
comments
collection
share

真实案例!java自定义注解实战!

作者站长头像
站长
· 阅读数 17

1.邂逅注解

在开发过程中,我们用过很多注解。例如 @Override、@Autowired、@RestController 等。

注解官方解释:

从 JDK5 开始,Java 增加对元数据的支持,也就是注解,注解与注释是有一定区别的,可以把注解理解为代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过注解开发人员可以在不改变原有代码和逻辑的情况下在源代码中嵌入补充信息。

通俗来讲,注解就像访问某资源的一种限制条件,你只有满足了这个条件,你才有权限进行某些操作。

例如你如果去看周杰伦演唱会,你需要先掏钱买门票,不然会被门口的工作人员拦下来。

在实际开发中,创建注解很简单,如何执行注解的限制条件才是关键。

所以自定义注解通常会和 SpringMVC 的拦截器或者 AOP 一起使用。

拦截器和 AOP 可以看作演唱会门口的工作人员。你买了演唱会门票,工作人员就让你进去看演唱会。某次请求满足了注解的限制条件,拦截器和 AOP 就放行该请求,继续往下执行。

2.自定义注解

创建的自定义注解主要包含三部分:

  • 1.注解名字前面用 @interface 进行标识

  • 2.元注解

  • 3.属性

真实案例!java自定义注解实战!

元注解

元注解又叫做注解的注解,其实就是对该注解的一些解释说明。例如我们买的演唱会门票,上面标注的有时间、地点、座位等。

我们常用的元注解主要有两个:@Target 和 @Retention

@Retention 表示该注解的使用时间,里面的变量是一个枚举。

真实案例!java自定义注解实战!

RetentionPolicy.RUNTIME 表示该注解在程序运行时会被用到,我们在实际开发中也经常使用该变量。

@Target 表示该注解作用的位置,里面的变量是一个枚举。

真实案例!java自定义注解实战!

  • ElementType.TYPE:作用在类、接口或枚举上面
  • ElementType.FIELD:作用在成员变量上面
  • ElementType.METHOD:作用在方法上面
  • ElementType.PARAMETER:作用在方法参数上面
  • ElementType.CONSTRUCTOR:作用在构造器上面
  • ElementType.LOCAL_VARIABLE:作用在局部变量上面
  • ElementType.ANNOTATION_TYPE:作用在注解上面
  • ElementType.PACKAGE:作用在包上面

在实际开发中我们会经常用到 TYPE、METHOD、PARAMETER。

属性

元注解是对注解作了一些通用的说明,而注解的属性对注解作了一些特定的说明。

真实案例!java自定义注解实战!

语法格式:

数据类型 变量名() default 默认值

注解的属性不是必须的。我们在创建注解属性的时候如果没有设置默认值,那么在使用的时候必须设置值,例如:

真实案例!java自定义注解实战!

真实案例!java自定义注解实战!

如果注解的属性只有一个,并且属性名为 value(),那么在使用注解的时候,可以忽略属性名和 ‘=’号,直接在括号里为其赋值,例如:

真实案例!java自定义注解实战!

真实案例!java自定义注解实战!

3.实战

这三个自定义注解的小案例都是基于 SpringBoot 进行开发,后面会给出完整代码。

依赖:

spring-boot-starter-web
lombok
java-jwt
spring-boot-starter-data-redis
hutool-all
redisson-spring-boot-starter
aspectjweaver

application.yml:

真实案例!java自定义注解实战!

3.1 自定义注解和拦截器获取当前登录用户

1.创建注解

该注解作用在方法参数上。

真实案例!java自定义注解实战!

2.创建拦截器

首先获取 token,然后用 jwt 校验 token 信息,再根据 token 信息从 Redis 里面获取用户信息。

最关键的一步是将用户信息存放到 request 域里面。

真实案例!java自定义注解实战!

3.配置注解解析器

真实案例!java自定义注解实战!

注解解析器的执行流程是必须要满足 supportsParameter,然后才会执行 resolveArgument。

也就是需要满足下面条件:

真实案例!java自定义注解实战!

当参数的注解是 @CurrentUser ,参数的类型是 User 类的时候,就会从 Request 域中查出用户信息,并赋值给 @CurrentUser 注解标注的 user 参数。

4.注册拦截器和解析器

真实案例!java自定义注解实战!

5.controller

真实案例!java自定义注解实战!

6.测试

用户登录,返回 token 信息

真实案例!java自定义注解实战!

调用用户列表接口:

真实案例!java自定义注解实战!

真实案例!java自定义注解实战!

真实案例!java自定义注解实战!

3.2 自定义注解和拦截器实现接口限制功能

1.创建注解

真实案例!java自定义注解实战!

2.创建拦截器

核心逻辑就是将注解上设置的年龄和用户的年龄做对比。

真实案例!java自定义注解实战!

3.注册拦截器

真实案例!java自定义注解实战!

4.controller

真实案例!java自定义注解实战!

5.测试

当前用户年龄 12,自定义注解年龄的限制是 18岁。

真实案例!java自定义注解实战!

3.3 自定义注解和 AOP、Redisson 防止重复提交

1.创建注解

真实案例!java自定义注解实战!

2.配置 redis 和 redisson

真实案例!java自定义注解实战!

真实案例!java自定义注解实战!

3.配置 aop

核心就是使用 redis 的分布式锁,在访问接口之前先获取锁,获取锁成功再访问该接口。在锁失效的时间内重复点击该接口,如果获取锁失败,就返回错误信息。

真实案例!java自定义注解实战!

4.controller

真实案例!java自定义注解实战!

5.测试

真实案例!java自定义注解实战!

4.完整代码

gitee:

https://gitee.com/zhifou-tech/spring-annotation.git

百度网盘:

链接:https://pan.baidu.com/s/1vq8NsO3rp1qGmqkoCSOvJQ?pwd=1234 
提取码:1234