個人做的網(wǎng)站搜索引擎優(yōu)化怎么做
在開發(fā)過程中,很多時候我們會使用ThreadLocal來臨時緩存數(shù)據(jù),當(dāng)一次數(shù)據(jù)請求執(zhí)行完成后需要主動執(zhí)行釋放當(dāng)前ThreadLocal緩存數(shù)據(jù)資源,防止未能及時釋放導(dǎo)致下一次訪問時候ThreadLocal依然保持上一次緩存的數(shù)據(jù)。
spring提供兩種方式去監(jiān)聽一次請求完成事件。
1、HandlerInterceptor -> afterCompletion 使用攔截方式,再執(zhí)行完成后執(zhí)行afterCompletion
2、ApplicationListener -> ServletRequestHandledEvent ,ApplicationListener 提供的是監(jiān)聽那種事件類型,ServletRequestHandledEvent 就是一次請求結(jié)束后的事件。
通過上述兩種方式可以很方便的在一次請求完成移除當(dāng)前線程ThreadLocal。
ThreadLocal 工具
public class ThreadLocal2UserSessionUtil {private static final ThreadLocal<Object> LOCAL = new ThreadLocal<>();/*** 設(shè)置數(shù)據(jù)** @param paramMap*/public static void set(Map<String, Object> paramMap) {LOCAL.set(paramMap);}/*** 獲取值** @return*/public static Map<String, Object> get() {if (Objects.isNull(LOCAL.get())) {return new HashMap<>();} else {return (Map<String, Object>) LOCAL.get();}}/*** 獲取值** @return*/public static Object get(String key) {Map<String, Object> resMap = (Map<String, Object>) LOCAL.get();if (null == resMap) {return null;}return (null != resMap.get(key)) ? resMap.get(key) : null;}/*** 每次取出數(shù)據(jù)后必須清空 否則就會出現(xiàn)值重復(fù)*/public static void remove() {LOCAL.remove();}/*** 獲取app登錄token** @return*/public static String getToken4App() {Map<String, Object> map = get();return (null == map) ? "" : (String) map.get(EncryptReqParamNameConstant.PARAM_TOKEN);}/*** 初始化數(shù)值** @return*/public static void pushUserToken4App(String appToken) {Map<String, Object> localMap = get();if (StringUtil.isNotBlank(appToken)) {localMap.put(EncryptReqParamNameConstant.PARAM_TOKEN, appToken);set(localMap);}}/*** 初始化數(shù)值** @return*/public static void pushUserId4App(Long userId) {Map<String, Object> localMap = get();if (null != userId) {localMap.put(EncryptReqParamNameConstant.USER_ID, userId);set(localMap);}}/*** 初始化數(shù)值 注意這里只有加解密才將用戶id放入** @return*/public static Long getUserId4App() {Map<String, Object> map = get();return (null == map) ? null : (Long) map.get(EncryptReqParamNameConstant.USER_ID);}
}
HandlerInterceptor 方式
@Slf4j
@Component
public class ThreadLocalRemoveInterceptor implements HandlerInterceptor {@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);ThreadLocal2UserSessionUtil.remove();}
}
在web控制器中加入監(jiān)聽器
@Configuration
public class PathPrefixMvcConfigurer implements WebMvcConfigurer {@Autowiredprivate ThreadLocalRemoveInterceptor threadLocalRemoveInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(threadLocalRemoveInterceptor).addPathPatterns("/*");}
}
2、通過監(jiān)聽器方式
@Slf4j
@Component
public class ServletRequestHandledEventListener implements ApplicationListener<ServletRequestHandledEvent> {@Overridepublic void onApplicationEvent(ServletRequestHandledEvent event) {ThreadLocal2UserSessionUtil.remove();}
}
完成