ホームページ  >  記事  >  Java  >  Java カスタム フィルターとインターセプターは ThreadLocal スレッド クロージャーを実装します。

Java カスタム フィルターとインターセプターは ThreadLocal スレッド クロージャーを実装します。

WBOY
WBOY転載
2023-05-15 23:40:05902ブラウズ

スレッド クロージャ

スレッド クロージャは、通常、次の 3 つの方法によって行われます。

  • アドホック スレッド クロージャ: プログラム コントロールの実装、最悪、無視します

  • スタック クロージャ: ローカル変数、同時実行の問題なし

  • Threadローカル スレッド クロージャ: 特に優れたクロージャ メソッド

メソッド 2 が最も一般的に使用されます。変数はインターフェイスで定義されます。この記事では主にメソッド 3 について説明します。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;
    }
}

アプリケーション クラスのスタートアップ クラス # でカスタム フィルターとインターセプターを構成します。 ##
/**
 * 
 * @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 スレッド クロージャーを実装します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。