首页 > 其他分享 >如何l利用`ThreadLocal`、`HandlerInterceptor`、`HandlerMethodArgumentResolver`来完成代码优化

如何l利用`ThreadLocal`、`HandlerInterceptor`、`HandlerMethodArgumentResolver`来完成代码优化

时间:2023-11-16 17:11:05浏览次数:40  
标签:TUser HandlerMethodArgumentResolver void ThreadLocal 代码优化 user public

核心类 ThreadLocalHandlerInterceptorHandlerMethodArgumentResolver

1. ThreadLocal
2. WebMvcConfigurer 
	- addArgumentResolvers
3. HandlerMethodArgumentResolver
	- supportsParameter
	- resolveArgument
  • ThreadLocal:可以理解为一个线程安全的Map。

    // 用户上下文
    public class UserContext {
    
        private static ThreadLocal<TUser> userThreadLocal = new ThreadLocal<>();
    
        public static void setUser(TUser tUser) {
            userThreadLocal.set(tUser);
        }
    
        public static TUser getUser() {
            return userThreadLocal.get();
        }
        
        public static void remove(){
            userThreadLocal.remove();
        }
    }
    
  • HandlerInterceptor:接口是Spring MVC中的一种拦截器,用于在请求处理过程中进行预处理和后处理操作。

    HandlerInterceptor接口定义了三个方法,分别是:
    
    1. `preHandle`: 在请求处理方法之前执行。这允许你在请求被处理之前执行一些操作,例如验证用户身份或日志记录。
    		- 一般我们接口都需要带token,会获取用户信息。
    		- 我们可以在`preHandle`方法中,放入user。
    		- UserContext.setUser(tUser);
    
    2. `postHandle`: 在请求处理方法之后,视图渲染之前执行。这允许你在返回响应之前修改模型数据或视图。
    
    3. `afterCompletion`: 在整个请求处理完成之后执行。这是在响应已经被发送给客户端之后执行的方法,通常用于清理资源或执行一些最终的操作。
    		- 请求结束之后,可以使用 UserThreadLocal.remove(); 
    		- 好处:避免内存泄露。
    		- 原因:ThreadLocalMap 中使用的 key 为 ThreadLocal 的弱引用,弱引用的特点是,如果这个对象只存在弱引用,那么在下一次垃圾回收的时候必然会被清理掉。
    
  • HandlerInterceptor注册进WebMvcConfigurer

    @Configuration
    public class WebMVCConfig implements WebMvcConfigurer {
        @Autowired
        private LoginInterceptor loginInterceptor;
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
        }
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 将处理器拦截器注册进WebMvcConfig
            registry.addInterceptor(loginInterceptor);
        }
    }
    
  • UserThreadLocal总结

    1. 在本次请求中,任何地方用到user的地方,我们都可以使用:SysUser sysUser = UserThreadLocal.get();
    
  • 思考

    1. 每次获取user对象,都需要写:SysUser sysUser = UserThreadLocal.get();
    2. 能不能不写?
    
  • 解决办法:HandlerMethodArgumentResolver-处理方法参数解析器

    @Component
    public class UserArgumentResolver implements HandlerMethodArgumentResolver {
    
        @Override
        public boolean supportsParameter(MethodParameter parameter) {
            Class<?> parameterType = parameter.getParameterType();
            // 只有返回`true`时,`resolveArgument`方法才会执行。
            return parameterType == TUser.class;
        }
    
        @Override
        public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws 	 			Exception {
            	return UserContext.getUser();
        }
    }
    
  • UserArgumentResolver注册进WebMvcConfigurer

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Autowired
        private UserArgumentResolver userArgumentResolver;
        
        @Override
        public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
            resolvers.add(userArgumentResolver);
        }
    }
    
  • 代码实例

    // 这时候,请求不需要传user参数,我们的接口也能获取到user
    @Slf4j
    @GetMapping(value = "/test")
    public void test(TUser user) {
        log.info("user:{}",user);
    }
    
  • 总结

    1. 每次请求过来,都会经过`HandlerMethodArgumentResolver`-方法参数解析器,当参数类型为,`TUser`时,会从`ThreadLocal`中获取`TUser`,赋值给接口中的`user`参数。
    

标签:TUser,HandlerMethodArgumentResolver,void,ThreadLocal,代码优化,user,public
From: https://www.cnblogs.com/zzusjw/p/17836604.html

相关文章

  • 使用JWT、拦截器与ThreadLocal实现在任意位置获取Token中的信息,并结合自定义注解实现
    1.简介1.1JWTJWT,即JSONWebToken,是一种用于在网络上传递声明的开放标准(RFC7519)。JWT可以在用户和服务器之间传递安全可靠的信息,通常用于身份验证和信息交换。声明(Claims):JWT包含一组称为声明的信息,声明描述了一些数据。有三种类型的声明:注册声明(RegisteredClaims):这是......
  • Java中ThreadLocal说明 使用线程内变量,完成后需调用remove()方法将其移除,即使异常也
    Java中ThreadLocal说明,完成后需调用remove()方法将其移除,即使异常也记得remove()回收,创建ThreadLocal线程变量publicstaticThreadLocalthreadLocal=newThreadLocal<>();1、ThreadLocal是什么ThreadLocal,即线程变量,是一个以ThreadLocal对象为键、任意对象为值的存储......
  • 小程序性能提速秘籍:CSS代码优化,让小程序轻松翻倍酷炫!
    引言:Hello,小程序开发小能手们!是不是有时候发现小程序的加载速度有点慢,页面样式显示有点乱?别急,今天小编要传授一招“CSS代码优化”的技能,让你的小程序风驰电掣,页面秒变酷炫!我们要一起玩得开心,不让性能问题影响我们的小程序!......
  • 11 13vue代码优化
    今天基本学完了前端vue,整理vue:接口封装//定制请求的实例//导入axios npminstallaxiosimportaxiosfrom'axios';import{ElMessage}from'element-plus'//定义一个变量,记录公共的前缀 , baseURL//constbaseURL='http://localhost:8080';constbaseURL=......
  • 面试10000次依然会问的【ThreadLocal】,你还不会?
    ThreadLocal简介与基本概念ThreadLocal,即线程局部变量,是Java语言中用于实现线程数据隔离的一个重要类。这种机制允许在多线程环境中,每个线程都有自己的变量副本,从而使得每个线程都可以独立地改变自己的副本,而不会影响其他线程的副本。这种特性对于保证线程安全至关重要,尤其是在处......
  • 11 11 vue3代码优化
     使用axios发送异步请求是这种格式,现在异步请求都封装到api中。说法如下:接口调用的js代码一般都会封装到js文件中,并一函数的形式暴露给外部,例如: 这张图片包括了没有参数和有参数的两种情况 然后在组件中的script中调用函数就行,但这样不行,好像跟什么同步异步有关,反正这样......
  • Matlab代码优化之道
    ​ 一、遵守PerformanceAcceleration的规则关于什么是“PerformanceAcceleration”请参阅matlab的帮助文件。1、只有使用以下数据类型,matlab才会对其加速:logical,char,int8,uint8,int16,uint16,int32,uint32,double而语句中如果使用了非以上的数据类型则不会加速,如numeric......
  • 小程序性能优化之JavaScript代码优化
    大家好,今天我们来聊一聊小程序性能优化中的JavaScript代码优化。在编程过程中,我们都喜欢轻松愉快,不想戴着沉重的“全局疯狂”帽子。但有时候,过度使用全局变量会让我们的程序变得难以维护,就像在一片大森林里找寻一个小木屋。这时候,我们就需要考虑一下,是不是该减轻一下我们的“全局疯......
  • ThreadLocal原理
    从ThreadLocal的get和set方法入手publicvoidset(Tvalue){Threadt=Thread.currentThread();ThreadLocalMapmap=getMap(t);if(map!=null)map.set(this,value);elsecreateMap(t,value);}......
  • JAVA-EE手写ThreadLocal源码实现一个线程一个连接对象------Java-Web项目
    手写ThreadLocalpackagecom.bjpowernode.ThreadLocal;importjava.util.HashMap;importjava.util.Map;publicclassMyThreadLocal<T>{privateMap<Thread,T>map=newHashMap<>();publicvoidset(To){//向threadLocal中绑定......