前言
自定义切面在实际应用中非常广泛,通常都是用作登录鉴权统一拦截,接口日志统一打印等,下面示范的是一个简单的登录鉴权切面,如需更多功能,例如权限,token校验也可以做在切面里。
一、引入Maven依赖
<!-- 切面依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
二、创建自定义注解
import java.lang.annotation.*;
/**
* 权限校验注解
* 使用该注解的类或者方法会被拦截鉴权
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface WebAccess {
/**
* 是否校验登录
*
* @return
*/
boolean login() default false;
}
三、创建切面
import com.mimoprint.ecdiyweb.annotation.WebAccess;
import com.mimoprint.ecdiyweb.common.UserContext;
import com.mimoprint.ecdiyweb.common.exception.BusinessException;
import com.mimoprint.ecdiyweb.common.model.LoginUser;
import com.mimoprint.ecdiyweb.common.model.ResponseCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Aspect
@Order(1)
@Slf4j
public class AuthorizeCheckAspect {
// 切点定义,top.haostore.web包下,所有以Controller结尾的类的所有方法
@Pointcut("execution(* top.haostore.web..*Controller.*(..))")
public void excudeService() {
}
// 切面增强,环绕增强
@Around("excudeService()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取方法的签名
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
// 获取方法@WebAccess注解
WebAccess webAccess = methodSignature.getMethod().getAnnotation(WebAccess.class);
// 没有方法注解,获取类@WebAccess注解
if (webAccess == null) {
Class clazz = joinPoint.getTarget().getClass();
webAccess = clazz.getAnnotation(WebAccess.class);
}
// @WebAccess注解为空,直接放行
if (webAccess == null || !webAccess.login()) {
return joinPoint.proceed();
}
// 否则,从登录态获取用户信息
LoginUser loginUser = UserContext.getLoginUser();
// 用户信息为空,说明用户未登录,抛出异常
if (loginUser == null) {
throw new BusinessException(ResponseCodeEnum.PAYMENT_REQUIRED.getCode(), ResponseCodeEnum.PAYMENT_REQUIRED.getMsg());
}
// 用户信息存在,放行
return joinPoint.proceed();
}
}
@各位掘金的小伙伴,如有任何Java技术方面疑问可私聊本人(wx:haostudydaydayup),一起探讨一起进步。