app 请求带上自身的“设备号id” 和手机号码 //首先自定义注解 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface SingleDeviceLogin { public String value() default "单点登陆"; } //在AOP中作切面,拦截左右标注注解的 方法 @Pointcut("@annotation(com.lifang.userapp.myannotation.SingleDeviceLogin)") public void annotationSignleDevice(){} //环绕通知:checkIsSigninLogin 主要作的是从redis中根据"手机号码"获取当前app的设备号; //若是没有则从数据库中获取设备号; 若是和当前传入的设备号不一样则,isEntryMethod 为false,不然为true @Around("annotationSignleDevice()") public Object AroundMethod(ProceedingJoinPoint joinpoint) throws Throwable { Object obj = null; boolean isEntryMethod = this.checkIsSigninLogin(joinpoint); if (isEntryMethod) { obj = joinpoint.proceed(); //执行业务代码 return obj; } else { Signature signaturn = joinpoint.getSignature(); Class returnType = ((MethodSignature)signaturn).getReturnType(); Object backNewInstance = returnType.newInstance(); Method methodStatus = returnType.getMethod("setStatus", int.class); Method methodMessage = returnType.getMethod("setMessage", String.class); methodStatus.invoke(backNewInstance, 2); methodMessage.invoke(backNewInstance, "该设备在别的手机上登陆,请从新登陆"); return backNewInstance; } } //登陆执行操做 把手机号和设备号 的对应关系放到 redis中 同时存入 数据库中; //对应的拦截方法 @SingleDeviceLogin(value = "取消收藏信息") public Response uncollect(HttpServletRequest request, HttpServletResponse response, PersonConterRequest personConterRequest){}