spring boot中如何使用AOP检测是否登录呢?
下文笔者讲述SpringBoot中借助AOP检测是否登录的方法及示例分享,如下所示
实现思路: 1.引入相应的依赖 2.编写AOP代码(切面类)例
pom.xml引用 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 2、创建插入标记 @Target({ElementType.METHOD}) // 只在对象方法上标记 @Retention(RetentionPolicy.Runtime) //运行时反射 public @interface Interceptor { String additionalMessage() default ""; } 3、实现切入类 @Aspect @Component @Slf4j public class LoggingAspect { @Autowired public StringredisTemplate redisTemplatelocate; private <T> T getSessionID(Object postData,Class<T> clazz){ return (T)postData; } @Around("@annotation(Interceptor)") //有标记的地方将实现以下和切入 public Object logExecutionTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { //获取切入方法的参数,就是前部请求的json数据 Object[] args = proceedingJoinPoint.getArgs(); //获取其中的sessionid // requestBase 实体类只有一个参sessionid , 做为其它实体类的父类,用于接收接口上传的参数。 RequestBase requestBase=getSessionID(args[0],RequestBase.class); log.info("sessionid:{}",requestBase.getSessionid()); //检测该sessionid 是否存在(redis) if (requestBase.getSessionid()==null || !redisTemplatelocate.hasKey(requestBase.getSessionid())) { //用户未登陆 throw new Exception("用户未登陆"); } //获取 request 和 response ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()); log.info("request:{}",servletRequestAttributes.getRequest()); log.info("response:{}",servletRequestAttributes.getResponse()); MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature(); String className = methodSignature.getDeclaringType().getSimpleName(); String methodName = methodSignature.getMethod().getName(); Instant startTime = Instant.now(); //实行被切入的方法 Object result = proceedingJoinPoint.proceed(); String additionalMessage = methodSignature.getMethod().getAnnotation(Interceptor.class).additionalMessage(); long elapsedTime = Duration.between(startTime, Instant.now()).toMillis(); log.info("Class Name: {}, Method Name: {}, Additional Message: {}, Elapsed Time: {}ms", className, methodName, additionalMessage, elapsedTime); log.info("Result: {}", result); return result; } } 4.建立api接口,在需要检测的方法上加入@Interceptor 就完成切入的检测。 @RestController @Slf4j public class ExampleController { @PostMapping("/t1") @Interceptor(additionalMessage = "要求检测登录") @ResponseBody public ResponseEntity<RequestBase> getData(@RequestBody DataRequest req) { try { return new ResponseEntity<>(req, HttpStatus.OK); } catch (Exception e) { return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); } } } 5.实体类 @Data public class DataRequest extends RequestBase { private String name; } @Data public class RequestBase{ private String sessionid; } //@Pointcut("execution(public * com.example.myapp..*.*(..))") @Aspect @Component @Slf4j public class LoginExecution { @Autowired public StringRedisTemplate redisTemplatelocate; private <T> T getSessionID(Object postData,Class<T> clazz){ return (T)postData; } //切入点: com.aop.ttt 下的所有public 方法 @Pointcut("execution(public * com.aop.ttt..*.*(..))") public void publicMethods() {} @Around("publicMethods()") public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable { //获取切入方法的参数,就是前部请求的json数据 Object[] args = joinPoint.getArgs(); //获取其中的sessionid // requestBase 实体类只有一个参sessionid , 做为其它实体类的父类,用于接收接口上传的参数。 RequestBase requestBase=getSessionID(args[0],RequestBase.class); log.info("sessionid:{}",requestBase.getSessionid()); //检测该sessionid 是否存在(redis) if (requestBase.getSessionid()==null || !redisTemplatelocate.hasKey(requestBase.getSessionid())) { //用户未登陆 throw new Exception("用户未登陆"); } //获取 request 和 response ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()); log.info("request:{}",servletRequestAttributes.getRequest()); log.info("response:{}",servletRequestAttributes.getResponse()); MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); String className = methodSignature.getDeclaringType().getSimpleName(); String methodName = methodSignature.getMethod().getName(); Instant startTime = Instant.now(); //实行被切入的方法 Object result = joinPoint.proceed(); long elapsedTime = Duration.between(startTime, Instant.now()).toMillis(); log.info("Class Name: {}, Method Name: {}, Elapsed Time: {}ms", className, methodName, elapsedTime); log.info("Result: {}", result); return result; } }
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。