Java自定義過(guò)濾器和攔截器實(shí)現(xiàn)ThreadLocal線程封閉
線程封閉
線程封閉一般通過(guò)以下三個(gè)方法:
- Ad-hoc線程封閉:程序控制實(shí)現(xiàn),最糟糕,忽略
- 堆棧封閉:局部變量,無(wú)并發(fā)問(wèn)題
- ThreadLocal線程封閉:特別好的封閉方法
方法2是最常用的,變量定義在接口內(nèi),本文主要講解方法三,SpringBoot項(xiàng)目通過(guò)自定義過(guò)濾器和攔截器實(shí)現(xiàn)ThreadLocal線程封閉。實(shí)現(xiàn)Filter接口自定義過(guò)濾器和繼承HandlerInterceptorAdapter自定義攔截器。
ThreadLocal線程封閉實(shí)現(xiàn)步驟
封裝ThredLocal的方法
/**
* <p>自定義RequestHolder</p></p>
*
* @Author zjq
* @Date 2021/12
*/
public class RequestHolder {
private final static ThreadLocal<Long> requestHolder = new ThreadLocal<>();
public static void set(Long id) {
requestHolder.set(id);
}
public static Long get() {
return requestHolder.get();
}
public static void remove() {
requestHolder.remove();
}
}
自定義過(guò)濾器
自定義定義攔截器繼承Filter接口,實(shí)現(xiàn)ThredLocal.add()方法
/**
* <p>自定義過(guò)濾器</p>
*
* @Author zjq
* @Date 2021/12/7
*/
@Slf4j
public class HttpFilter implements Filter {
/**
* 為Filter初始化 提供支持
*
* @param filterConfig
* @throws ServletException
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 攔截到要執(zhí)行的請(qǐng)求時(shí),doFilter就會(huì)執(zhí)行。這里我們可以寫對(duì)請(qǐng)求和響應(yīng)的預(yù)處理。
* FilterChain把請(qǐng)求和響應(yīng)傳遞給下一個(gè) Filter處理
*
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//把普通servlet強(qiáng)轉(zhuǎn)成httpServlet
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
Long threadId = Thread.currentThread().getId();
log.info("do filter,threadId:{} servletPath:{}", threadId, httpServletRequest.getServletPath());
//把當(dāng)前線程id放入requestHolder
RequestHolder.set(threadId);
//放行
filterChain.doFilter(httpServletRequest, servletResponse);
}
/**
* Filter 實(shí)例銷毀前的準(zhǔn)備工作
*/
@Override
public void destroy() {
}
}
自定義攔截器
自定義攔截器在線程使用完畢后移除ThredLocal中內(nèi)容,避免內(nèi)存溢出
/**
* <p>自定義攔截器</p>
*
* @Author zjq
* @Date 2021/12/7
*/
@Slf4j
public class HttpInterceptor extends HandlerInterceptorAdapter {
/**
* 攔截處理程序的執(zhí)行。在 HandlerMapping 確定合適的處理程序?qū)ο笾?,?HandlerAdapter 調(diào)用處理程序之前調(diào)用。
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("preHandle執(zhí)行。。。");
return true;
}
/**
* 請(qǐng)求處理完成后(渲染視圖后)的回調(diào)。將在處理程序執(zhí)行的任何結(jié)果上調(diào)用,從而允許進(jìn)行適當(dāng)?shù)馁Y源清理。
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
RequestHolder.remove();
log.info("afterCompletion執(zhí)行。。。");
return;
}
}
Application類啟動(dòng)類中配置自定義過(guò)濾器和攔截器
/**
*
* @author zjq
*/
@SpringBootApplication
public class Application extends WebMvcConfigurationSupport {
public static void main(String[] args) {
SpringApplication.run(ConcurrencyApplication.class, args);
}
/**
* 自定義過(guò)濾器
* @return
*/
@Bean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new HttpFilter());
//設(shè)置自定義過(guò)濾器攔截的url
filterRegistrationBean.addUrlPatterns("/threadLocal/*");
return filterRegistrationBean;
}
/**
* 定義自定義攔截器原先需要繼承WebMvcConfigurerAdapter
* SpringBoot2.0后WebMvcConfigurerAdapter被定義成過(guò)時(shí)了,推薦使用繼承WebMvcConfigurationSupport
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new HttpInterceptor()).addPathPatterns("/**");
}
}
定義調(diào)用接口
/**
* ThreadLocal測(cè)試controller
* @author zjq
*/
@Controller
@RequestMapping("/threadLocal")
public class ThreadLocalController {
@RequestMapping("/test")
@ResponseBody
public Long test() {
return RequestHolder.get();
}
}
請(qǐng)求訪問(wèn)驗(yàn)證
訪問(wèn)調(diào)用接口http://localhost:8080/threadLocal/test,控制臺(tái)輸出如下:

到此這篇關(guān)于Java自定義過(guò)濾器和攔截器實(shí)現(xiàn)ThreadLocal線程封閉的文章就介紹到這了,更多相關(guān)Java ThreadLocal線程封閉內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot集成PDFBox實(shí)現(xiàn)電子簽章的代碼詳解
Apache PDFBox 是一個(gè)開(kāi)源的 Java 庫(kù),用于處理 PDF 文檔,它提供了一系列強(qiáng)大的功能,包括創(chuàng)建、渲染、拆分、合并、加密、解密 PDF 文件,以及從 PDF 中提取文本和元數(shù)據(jù)等,本文給大家介紹了SpringBoot集成PDFBox實(shí)現(xiàn)電子簽章,需要的朋友可以參考下2024-09-09
JavaEE多線程中阻塞隊(duì)列的項(xiàng)目實(shí)踐
本文主要介紹了JavaEE多線程中阻塞隊(duì)列的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-09-09
Java設(shè)計(jì)模式之java模板方法模式詳解
這篇文章主要介紹了Java設(shè)計(jì)模式模板方法模式(Template)用法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-09-09
ConditionalOnProperty配置swagger不生效問(wèn)題及解決
這篇文章主要介紹了ConditionalOnProperty配置swagger不生效問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
Mybatis mapper接口動(dòng)態(tài)代理開(kāi)發(fā)步驟解析
這篇文章主要介紹了Mybatis mapper接口動(dòng)態(tài)代理開(kāi)發(fā)步驟解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
Java之MultipartFile和File類型互轉(zhuǎn)方式
這篇文章主要介紹了Java之MultipartFile和File類型互轉(zhuǎn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
springboot調(diào)用HTML文件注意事項(xiàng)及說(shuō)明
這篇文章主要介紹了springboot調(diào)用HTML文件注意事項(xiàng)及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
解決MybatisPlus批量插入數(shù)據(jù)報(bào)錯(cuò):Error getting generated 
在使用MybatisPlus進(jìn)行批量插入數(shù)據(jù)時(shí)遇到空指針異常錯(cuò)誤,分析原因是由于主鍵生成策略導(dǎo)致的,嘗試通過(guò)設(shè)置useGeneratedKeys屬性解決問(wèn)題,但因批量插入方法限制,該方法未能成功,最終通過(guò)自定義mapper方法實(shí)現(xiàn)批量插入,解決了問(wèn)題2024-09-09
java開(kāi)發(fā)BeanUtils類解決實(shí)體對(duì)象間賦值
這篇文章主要為大家介紹了java開(kāi)發(fā)中使用BeanUtils類實(shí)現(xiàn)實(shí)體對(duì)象之間的賦值有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步學(xué)有所得2021-10-10
從零開(kāi)始Mybatis連接數(shù)據(jù)庫(kù)的方法
這篇文章主要介紹了Mybatis連接數(shù)據(jù)庫(kù)的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02

