中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java自定義過濾器和攔截器實現ThreadLocal線程封閉

發布時間:2022-08-05 13:49:46 來源:億速云 閱讀:142 作者:iii 欄目:開發技術

本文小編為大家詳細介紹“Java自定義過濾器和攔截器實現ThreadLocal線程封閉”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Java自定義過濾器和攔截器實現ThreadLocal線程封閉”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

線程封閉

線程封閉一般通過以下三個方法:

  • Ad-hoc線程封閉:程序控制實現,最糟糕,忽略

  • 堆棧封閉:局部變量,無并發問題

  • ThreadLocal線程封閉:特別好的封閉方法

方法2是最常用的,變量定義在接口內,本文主要講解方法三,SpringBoot項目通過自定義過濾器和攔截器實現ThreadLocal線程封閉。實現Filter接口自定義過濾器和繼承HandlerInterceptorAdapter自定義攔截器。

ThreadLocal線程封閉實現步驟

封裝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();
    }

}

自定義過濾器

自定義定義攔截器繼承Filter接口,實現ThredLocal.add()方法

/**
 * <p>自定義過濾器</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 {

    }

    /**
     * 攔截到要執行的請求時,doFilter就會執行。這里我們可以寫對請求和響應的預處理。
     * FilterChain把請求和響應傳遞給下一個 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強轉成httpServlet
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        Long threadId = Thread.currentThread().getId();
        log.info("do filter,threadId:{} servletPath:{}", threadId, httpServletRequest.getServletPath());
        //把當前線程id放入requestHolder
        RequestHolder.set(threadId);
        //放行
        filterChain.doFilter(httpServletRequest, servletResponse);
    }

    /**
     * Filter 實例銷毀前的準備工作
     */
    @Override
    public void destroy() {

    }
}

自定義攔截器

自定義攔截器在線程使用完畢后移除ThredLocal中內容,避免內存溢出

/**
 * <p>自定義攔截器</p>
 *
 * @Author zjq
 * @Date 2021/12/7
 */
@Slf4j
public class HttpInterceptor extends HandlerInterceptorAdapter {

    /**
     * 攔截處理程序的執行。在 HandlerMapping 確定合適的處理程序對象之后,在 HandlerAdapter 調用處理程序之前調用。
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("preHandle執行。。。");
        return true;
    }

    /**
     * 請求處理完成后(渲染視圖后)的回調。將在處理程序執行的任何結果上調用,從而允許進行適當的資源清理。
     * @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執行。。。");
        return;
    }
}

Application類啟動類中配置自定義過濾器和攔截器

/**
 * 
 * @author zjq
 */
@SpringBootApplication
public class Application extends WebMvcConfigurationSupport {

    public static void main(String[] args) {
        SpringApplication.run(ConcurrencyApplication.class, args);
    }

    /**
     * 自定義過濾器
     * @return
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new HttpFilter());
        //設置自定義過濾器攔截的url
        filterRegistrationBean.addUrlPatterns("/threadLocal/*");
        return filterRegistrationBean;
    }

    /**
     * 定義自定義攔截器原先需要繼承WebMvcConfigurerAdapter
     * SpringBoot2.0后WebMvcConfigurerAdapter被定義成過時了,推薦使用繼承WebMvcConfigurationSupport
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new HttpInterceptor()).addPathPatterns("/**");
    }
}

定義調用接口

/**
 * ThreadLocal測試controller
 * @author zjq
 */
@Controller
@RequestMapping("/threadLocal")
public class ThreadLocalController {

    @RequestMapping("/test")
    @ResponseBody
    public Long test() {
        return RequestHolder.get();
    }
}

請求訪問驗證

訪問調用接口http://localhost:8080/threadLocal/test,控制臺輸出如下:

Java自定義過濾器和攔截器實現ThreadLocal線程封閉

讀到這里,這篇“Java自定義過濾器和攔截器實現ThreadLocal線程封閉”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

普兰县| 晋中市| 河池市| 泊头市| 南充市| 新宁县| 吕梁市| 九龙城区| 龙山县| 邵武市| 安仁县| 双城市| 延川县| 石台县| 昌江| 肇州县| 汾西县| 玛多县| 娄烦县| 普陀区| 徐汇区| 玉山县| 大庆市| 灵山县| 宁明县| 永平县| 绵竹市| 名山县| 光泽县| 大石桥市| 辽宁省| 扎鲁特旗| 孟村| 桑植县| 大兴区| 宣威市| 常熟市| 荣昌县| 望奎县| 忻城县| 宜宾县|