目标
自定义接口屏蔽统一的登录拦截校验注解@LoginIgnore。
实现
创建模块中定义注解类 @LoginIgnore。
package com.server.common.annotation;
import java.lang.annotation.*;
/**
* 该注解主要用于标记不需要登录的接口
* 标注该注解的方法会自动屏蔽统一的登录拦截校验逻辑
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface LoginIgnore {}
上面代码中存在三个元注解及一个简单的自定义注解声明。这三个元注解的含义为:
@Documented- 将该注解包含到
Javadoc中。
- 将该注解包含到
@Retention(RetentionPolicy.RUNTIME)@Retention作用是指定该注解的生命周期。RetentionPolicy.RUNTIME则表示该注解在运行时依然存在。
@Target({ElementType.METHOD})@Target限制的该注解的作用范围。ElementType.METHOD表示该注解只能标记在方法上。
创建切面类
@Component
@Aspect
@Slf4j
public class CommonLoginAspect {
/**
* 切点表达式
*/
private static final String POINT_CUT = "execution(* com.server.modules.*.controller..*(..))";
/**
* 切点模版方法
*/
@Pointcut(value = POINT_CUT)
public void loginAuth() {}
/**
* 切点环绕增强逻辑
*/
@Around("loginAuth()")
public Object loginAuthAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
if (checkNeedCheckLoginInfo(proceedingJoinPoint)) {
// ...code
}
return proceedingJoinPoint.proceed();
}
/**
* 校验是否需要校验登录信息
* @param proceedingJoinPoint
* @return true 需要检验登录信息。false 不需要
*/
private boolean checkNeedCheckLoginInfo(ProceedingJoinPoint proceedingJoinPoint) {
Signature signature = proceedingJoinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
return !method.isAnnotationPresent(LoginIgnore.class);
}
// ...code
}
这个切面类稍稍有些许复杂。
整体流程如下:
1.首先设置 @Component 该类标记为 Spring 容器的 Bean。
2.设置 @Aspect 注解将该类标记为切面类。
3.声明切点表达式 POINT_CUT。
"execution(* com.server.modules.*.controller..*(..))"execution表示切点类型为方法执行。*返回值可以是任意类型。- 包路径为
com.server.modules.*下的任意子包。 - 子包中所有
controller下的所有方法。 *(..)表示匹配任意方法名和参数的方法
4.声明切点模版方法
- 将上述定义的切点表达式注入方法
@Pointcut(value = POINT_CUT)- 该方法不需要实现,只需要定义。
- 要注意该方法返回值必须为
void,访问修饰符必须是public,方法体和参数列表页都必须是空。
5.切点环绕增强
@Around("loginAuth()")@Around 注解的作用是定义切点环绕增强逻辑。- 在上面示例中,
loginAuthAround方法中的代码会在被拦截方法执行前后运行
6.判断是否需要登录校验
checkNeedCheckLoginInfo方法中基本属于固定写法。- 获取切点的相关信息
proceedingJoinPoint.getSignature();
- 由于切点是方法,所以可以强转为
MethodSignature。 - 获取切点映射的方法对象
methodSignature.getMethod();
- 判断该方法是否被
@LoginIgnore标记,可以理解这里就是将切面与注解类做关联。method.isAnnotationPresent(LoginIgnore.class);
通过以上操作即可完成自定义注解的大致流程。以上内容纯属个人刚学的理解,如果有啥问题欢迎大佬指出。