谢谢你们的阅读uu们!~~
下午这部分内容是aop往后啦,大家要明确一个思路,用aop进行简化操作更加方便
紧接上部分~
登录校验
如何判断是否登录状态?
– 判断请求头里面是否包含token字符串
– 根据token查询redis
如何实现?
– 原始方式:在需要判断登录的controller进行上面判断(token和redis)
– 如果使用原始方式,功能肯定可以实现的,但是造成有大量重复代码
– 对这样方式进行优化
如何优化?
– 使用自定义注解 + aop 进行优化(一定要熟悉哦!!!不然后面写不出来os)
- aop基础知识
- aop实现流程
- 方法:
- 创建注解
-
//登录判断 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface GuiguLogin {}
创建切面类
-
@Component @Aspect //切面类 public class GuiguLoginAspect {@Autowiredprivate RedisTemplate redisTemplate;//环绕通知,登录判断//切入点表达式:指定对哪些规则的方法进行增强@Around("execution(* com.atguigu.daijia.*.controller.*.*(..)) && @annotation(guiguLogin)")public Object login(ProceedingJoinPoint proceedingJoinPoint,GuiguLogin guiguLogin) throws Throwable {//1 获取request对象RequestAttributes attributes = RequestContextHolder.getRequestAttributes();ServletRequestAttributes sra = (ServletRequestAttributes)attributes;HttpServletRequest request = sra.getRequest();//2 从请求头获取tokenString token = request.getHeader("token");//3 判断token是否为空,如果为空,返回登录提示if(!StringUtils.hasText(token)) {throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);}//4 token不为空,查询redisString customerId = (String)redisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX+token);//5 查询redis对应用户id,把用户id放到ThreadLocal里面if(StringUtils.hasText(customerId)) {AuthContextHolder.setUserId(Long.parseLong(customerId));}//6 执行业务方法return proceedingJoinPoint.proceed();}}
其中:
-
(execution(* com.atguigu.daijia.*.controller.*.*(..)) 这段代码 ‘ *.* ’ 表示这个包中的所有类中的所有方法,(..)表示里面的参数
-
@annotation(guiguLogin) 表示 方法上有这个注解