自定义注解实现AOP的登录校验

时间:2024-8-8    作者:老大夫    分类: 乐尚代驾


只需要在需要登录校验的controller上添加自定义的登录校验注解就好了

创建注解

package com.atguigu.daijia.common.login;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//登录校验注解
@Target(ElementType.METHOD)//运行的目标
@Retention(RetentionPolicy.RUNTIME)//在什么情况下运行,编译或运行时
public @interface GuiguLogin {

}

创建切面类

package com.atguigu.daijia.common.login;

import com.atguigu.daijia.common.constant.RedisConstant;
import com.atguigu.daijia.common.execption.GuiguException;
import com.atguigu.daijia.common.result.ResultCodeEnum;
import com.atguigu.daijia.common.util.AuthContextHolder;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Component
@Aspect  //表示这是切面类
public class GuiguLoginAspect {

    @Autowired
    private RedisTemplate redisTemplate;

    @Around("execution(* com.atguigu.daijia.*.controller.*.*(..)) && @annotation(guiguLogin)")//用环绕通知,登录判断,切点表达式
    public Object login(ProceedingJoinPoint proceedingJoinPoint, GuiguLogin guiguLogin) throws Throwable{
        //获取Request对象
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes)attributes;
        HttpServletRequest request = sra.getRequest();
        //从请求头获取token
        String token = request.getHeader("token");
        //判断token是否为空
        if(!StringUtils.hasText(token)){
            throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
        }
        //不为空就查询redis对应的用户id,把用户id存入到ThreadLocal当中
        String customerId =(String) redisTemplate.opsForValue().
                get(RedisConstant.USER_LOGIN_KEY_PREFIX+token);
        //执行业务方法
        if(StringUtils.hasText(customerId)){
            AuthContextHolder.setUserId(Long.parseLong(customerId));//自定义一个操作ThreadLocal存取数据的工具类
        }

        return proceedingJoinPoint.proceed();//执行业务方法
    }
}


扫描二维码,在手机上阅读

推荐阅读: