AOP实现上下文存储 --- 系统框架搭建(三)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: AOP实现上下文存储 --- 系统框架搭建(三)

前面我们说了redis实现单点登入和redis实现登录拦截,redis实现登入拦截可以和session一起连用,保证用户必须在登入的条件下,才可以进行网站的访问。

springBoot+redis实现登入拦截器--系统框架搭建(二)


1、项目需求


这篇文章介绍如何获取到我们需要的连接上下文信息,比如用户信息,可以存储一个全局变量,直接获取,这样在我们每次访问数据库的时候都可以获取到用户信息等我们需要的数据。这里需要注意的地方是,为了防止不同的用户登入存储出现线程不安全情况,所以有threalLocal来保存不同用户的信息,使用threalLocal的时候记得要remove掉缓存。

另外当有其他网站调用我们系统的时候,会出现没有登入人的情况,这时候可以用spring源码的接口InitializingBean在spring容器创建的时候,给我们当前系统默认登入管理员。


2、代码实例


先定义一个放上下文的util和实体类:


/**
 * 全文上下文
 *
 * @author keying
 */
public class ContextUtil implements InitializingBean {
    private static Context systemContext = new Context();
    private static ThreadLocal<Context> threadLocalContext = new ThreadLocal<>();
    public static Context getContext() {
        return threadLocalContext.get();
    }
    public static void setContext(Context context) {
        threadLocalContext.set(context);
    }
    public static void removeContext() {
        threadLocalContext.remove();
    }
    public static Context getSystemContext(){
        return systemContext;
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        systemContext.setUserId("admin");
    }
}
/**
 * 上下文
 *
 * @author keying
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Context {
    private String userId;
}

然后定义一个拦截器,拦截器里有我上篇文章redis实现单点登入的代码,已注释

/**
 * 登入拦截器
 *
 * @author keying
 * @date 2021/6/11
 */
@Configuration
@Slf4j
public class LoginConfiguration implements WebMvcConfigurer {
    @Resource
    private RedisTemplate redisTemplate;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册拦截器
        InterceptorRegistration interceptorRegistration = registry.addInterceptor(new HandlerInterceptor() {
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
               /* log.info("登入拦截器启动!!");
log.info("session是否存在:{}", request.getSession().getAttribute("name"));
                if (request.getSession().getAttribute("name") != null) {
                    redisTemplate.opsForValue().set("name", request.getSession().getAttribute("name"), 10,TimeUnit.SECONDS);
                    return true;
                }
log.info("request.getContextPath():{}", request.getContextPath());
                response.sendRedirect(request.getContextPath() + "/redis/single/system1");
                //如果设置为false时,被请求时,拦截器执行到此处将不会继续操作
                //如果设置为true时,请求将会继续执行后面的操作
                return false;*/
                return true;
            }
            @Override
            public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                ModelAndView modelAndView) throws Exception {
log.info("postHandle");
            }
            @Override
            public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                Exception ex) throws Exception {
log.info("afterCompletion");
            }
        });
        //所有路径都被拦截
       /* interceptorRegistration.addPathPatterns("/**");*/
        //添加不拦截路径
        interceptorRegistration.excludePathPatterns(
            //"/redis/single/login_page",
            "/redis/single/system1",
            "/redis/single/system2",
            "/redis/single/detection",
            "/**/*.html",
            "/**/*.js",
            "/**/*.css",
            "/**/*.woff",
            "/**/*.ttf"
        );
        interceptorRegistration = registry.addInterceptor(new HandlerInterceptor() {
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
                //加上下文
                Context context = getContext();
                ContextUtil.setContext(context);
                return true;
            }
            @Override
            public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                Exception ex) throws Exception {
                //一定要记得remove
                ContextUtil.removeContext();
            }
        });
        //拦截所有路径
        interceptorRegistration.addPathPatterns("/**");
    }
    private Context getContext() {
        //给一个虚拟的登入者
        return new Context("keying");
    }
}
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
接口返回aop.unknow-error,系统繁忙
创建门店返回aop.unknow-error,大多数是因为传入的门店详细地址、店铺经纬度、省市区号指向的不是同一个地点而造成的,出现此类问题时,ISV需要首先核对上述地址是否指向相同地方,经纬度是否填反,是否没有使用高德坐标系,省市区号是否不是国标,是否填错。
1246 0
|
7月前
|
Java 程序员 数据库
业务需求-用AOP记录系统操作日志
全栈老司机 程序员林中酒 更新了本文详细介绍了如何使用AOP(面向切面编程)记录系统操作日志的业务需求,包括需求分析、技术实现分析、数据库设计和代码实现等各个环节。您将了解如何高效、规范地实现这一功能
|
Java 调度 Spring
【Logback+Spring-Aop】实现全面生态化的全链路日志追踪系统服务插件「SpringAOP 整合篇」
【Logback+Spring-Aop】实现全面生态化的全链路日志追踪系统服务插件「SpringAOP 整合篇」
378 0
【Logback+Spring-Aop】实现全面生态化的全链路日志追踪系统服务插件「SpringAOP 整合篇」
|
存储 安全 Java
【Logback+Spring-Aop】实现全面生态化的全链路日志追踪系统服务插件「Logback-MDC篇」
【Logback+Spring-Aop】实现全面生态化的全链路日志追踪系统服务插件「Logback-MDC篇」
715 0
【Logback+Spring-Aop】实现全面生态化的全链路日志追踪系统服务插件「Logback-MDC篇」
|
缓存 Java 机器人
基于AOP模式实现系统告警
在开发的过程中会遇到各种各样的开发问题,服务器宕机、网络抖动、代码本身的bug等等。针对代码的bug,我们可以提前预支,通过发送告警信息来警示我们去干预,尽早处理。
219 0
基于AOP模式实现系统告警
|
监控 Java 数据库
Spring AOP从入门到放弃之自定义注解收集系统日志
希望的效果为 需求 用户点击了某个界面,请求了后台某个接口。接口请求到后台后,记录请求的数据到数据库中。 实现方式 1、自定义一个注解,被加注解的方法,请求的数据被保存下来 2、定义一个aop 去拦截被注解的方法 3、写一个线程池、执行拦截后的逻辑。
1671 0
bboss aop 系统全局属性管理
Bboss aop 框架在1.0.6版本中增加全局属性配置管理功能,并提供了相应的接口来获取这些属性,本节详细介绍。   bboss 项目下载地址: https://sourceforge.
742 0
|
3月前
Micronaut AOP与代理机制:实现应用功能增强,无需侵入式编程的秘诀
AOP(面向切面编程)能够帮助我们在不修改现有代码的前提下,为应用程序添加新的功能或行为。Micronaut框架中的AOP模块通过动态代理机制实现了这一目标。AOP将横切关注点(如日志记录、事务管理等)从业务逻辑中分离出来,提高模块化程度。在Micronaut中,带有特定注解的类会在启动时生成代理对象,在运行时拦截方法调用并执行额外逻辑。例如,可以通过创建切面类并在目标类上添加注解来记录方法调用信息,从而在不侵入原有代码的情况下增强应用功能,提高代码的可维护性和可扩展性。
73 1
|
1月前
|
安全 Java 编译器
什么是AOP面向切面编程?怎么简单理解?
本文介绍了面向切面编程(AOP)的基本概念和原理,解释了如何通过分离横切关注点(如日志、事务管理等)来增强代码的模块化和可维护性。AOP的核心概念包括切面、连接点、切入点、通知和织入。文章还提供了一个使用Spring AOP的简单示例,展示了如何定义和应用切面。
124 1
什么是AOP面向切面编程?怎么简单理解?