文章目录
- 一、为什么会用到自定义注解
- 二、关键参数说明
- 三、应用场景示例:统一token认证
- 1. 背景
- 2. 自定义Token注解
- 3. AOP上定义切面方法
- 4. 方法上应用
- 5. 总结
一、为什么会用到自定义注解
自定义注解可以帮助我们更好地组织和管理代码,提高代码的可读性和可维护性,还能实现高效的代码复用和解耦。通过自定义注解,可以将相关的处理逻辑集中管理。例如,可以创建一个用于校验参数的注解,集中处理所有的参数校验逻辑,避免在每个方法中重复编写校验代码。随着项目的发展,可能需要引入新的功能或对现有功能进行调整。自定义注解使得这些扩展更加容易实现,只需添加或修改注解处理逻辑,无需修改使用了注解的类或方法,这样有助于开发出更加清晰、结构化的代码。
二、关键参数说明
@interface
声明annotation类别的@interface作为注解文件,区别于常用的class、interface和enum
@Retention
注解运行在哪一个时期的,总共有三种,分别是SOURCE、CLASS和RUNTIME
SOURCE:注解只在源代码中保留,编译阶段会被丢弃,不会写入字节码。如@Override、@SuppressWarnings等。
CLASS:注解在编译后被保留在字节码文件中,但在运行时环境中不会被虚拟机保留。这是默认的保留策略。
RUNTIME:注解在编译后被保留在字节码文件中,并且在运行时可以通过反射机制读取。这种类型的注解最为强大,从而执行一些运行时的逻辑处理。
@Target
注解用在哪上边,参数、方法、类…?
三、应用场景示例:统一token认证
1. 背景
现在有一个需求是对项目中部分方法接口进行安全加密认证,不然接口不让访问!
① 最笨的一种方法是在每个方法块中都加上安全认证的逻辑,功能可以实现,就是太蠢了,一大堆的重复废代码!
② 常用的一种思路是通过拦截器进行拦截处理,在拦截器中加上安全认证的逻辑,然后把不需要安全认证的请求地址放开。
③ 还有一种思路就是借助自定义注解了,然后在切面AOP上加上安全认证的逻辑,这样只需要在对应的方法中加上注解即可,接下来就是对这种思路的具体实现。
2. 自定义Token注解
/*** token验证自定义注解*/
@Retention(RetentionPolicy.RUNTIME) // 注解运行在哪一个时期的
@Target(ElementType.METHOD) // 注解用在哪上边
public @interface Token {
}
3. AOP上定义切面方法
@Aspect
@Component
@Slf4j
public class TokenAspect {/*** 定义一个切入点,参数是定义在哪个包。哪个类、哪个方法切入,关于切入点如何定义* @annotation(此处放自定义注解的全路径)*/@Pointcut("@annotation(com.test.demo.annotation.Token)")public void pointFn() {}/*** 环绕通知pointFn方法,切面方法需要有返回值,来代替被代理方法返回结果* 只有加入@Token注解的方法,才会执行到当前切面方法中*/@Around("pointFn()")public Object around(ProceedingJoinPoint point) throws Throwable {// 从header头中获取token信息String token = ServletUtils.getRequest().getHeader("token");log.info("对带有了@Token注解的方法,做check检查");if (StringUtils.isEmpty(token)) {return R.error(10001, "token为空,请携带token");}//TODO 依据token做验证
// // 如果token验证失败,则返回错误信息
// if (false) {
// return R.error(10002, "token验证失败");
// }return point.proceed();}
}
ServletUtils.getRequest()就是获取HttpServletRequest的一个方法,可以按照自己的实际需求获取,此处用到的是如下方法获取的:
public static HttpServletRequest getRequest() {RequestAttributes attributes = RequestContextHolder.getRequestAttributes();ServletRequestAttributes sra = (ServletRequestAttributes) attributes;return sra.getRequest();}
4. 方法上应用
5. 总结
这样,只要方法上加上了@Token注解,在执行该方法之前都会先执行TokenAspect类下的around方法,并对前端携带的token信息进行验证。如果前端没有传token信息或者token认证失败,则直接返回错误信息,如果认证成功,才能继续执行方法中的业务逻辑,可以有效避免在每个方法中重复编写token校验代码,提升代码的可维护性。