1. 程式人生 > >SpringMVC原始碼深度解析之攔截器&過濾器&檢視層&非同步原始碼分析

SpringMVC原始碼深度解析之攔截器&過濾器&檢視層&非同步原始碼分析

SpringMVC註解方式開啟檢視層

整合Jsp 檢視層

@Bean
public InternalResourceViewResolver internalResourceViewResolver() {
    // 1.需要字首
    InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
    // 2.需要字尾
    internalResourceViewResolver.setPrefix("/WEB-INF/view/");
    internalResourceViewResolver.setSuffix(".jsp");
    return internalResourceViewResolver;
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
完全基於Spring註解方式啟動SpringMVC

SpringMVC攔截器使用

攔截器與過濾器區別

攔截器和過濾器都是基於AOP實現的,能夠對請求之前和之後實現攔截

過濾器是基於Servlet實現的,對web請求之前和之後實現攔截

攔截器不需要依賴servlet,不僅可以實現web請求,還可以對其它方法攔截

SpringMVC攔截器的使用

1.自定義攔截器攔截請求Token

public class TokenInterceptor implements HandlerInterceptor {
    /**
     * 請求方法前置攔截,如果返回true 表示會執行到目標方法(請求方法) 如果返回false的情況下 則不會執行目標方法。
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getParameter("token");
        System.out.println(">>>>token<<<<:" + token);
        if (StringUtils.isEmpty(token)) {
            response.setStatus(500);
            response.getWriter().print(" token is null");
            return false;
        }
        // 執行我們的請求方法
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("<<<postHandle>>>>");
        // 請求之後執行。
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println(">>>afterCompletion<<<");
        // 請求之後執行。
    }
}

// 1.手動注入攔截器到Spring中
@Bean
public TokenInterceptor tokenInterceptor() {
    return new TokenInterceptor();
}
// 2.新增攔截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(tokenInterceptor()).addPathPatterns("/**");// 攔截所有的請求
}

注意:使用攔截器一定要關閉EnableWebMvc 否則攔截器不會生效。

加入這個註解EnableWebMvc重複注入了WebMvcConfigurationSupport,會覆蓋我們自定義的配置類

SpringMVC多執行緒非同步處理

使用非同步註解

@EnableAsync

@RequestMapping("/pay")
public String pay() {
    System.out.println(">>>1.開始呼叫pay<<<<<<< ThradName:" + Thread.currentThread().getName());
    payServie.pay();
    System.out.println(">>>3.結束呼叫pay<<<<<<< ThradName:" + Thread.currentThread().getName());
    return "pay";
}

使用非同步Callable 帶返回結果

@RequestMapping("/asyncPay")
@ResponseBody
public Callable<String> asyncPay() {
    System.out.println("1.開始執行payToMember>>>> name:" + Thread.currentThread().getName());
    Callable callable = new Callable<String>() {
        // 非同步的對吧!
        public String call() throws Exception {
            // 耗時的時間都可以放到這個裡面做 安卓裡面
            String member = memberService.member();
            return member;
        }
    };
    System.out.println("4.<<<<結束執行payToMember>>> name:" + Thread.currentThread().getName());
    return callable;
}
@Component
public class MemberService {

    /**
     * member方法單獨開啟一個執行緒處理請求
     *
     * @return
     */
    public String member() {
        try {
            System.out.println("2.開始呼叫會員服務介面... name:" + Thread.currentThread().getName());
            Thread.sleep(5000);
            System.out.println("3.結束呼叫會員服務介面.. name:" + Thread.currentThread().getName());
        } catch (Exception e) {

        }
        return "member";
    }
}

面試題:

SpringMVC專案中使用到多執行緒?

肯定是有。

為什麼要使用多執行緒?

提高我們響應的速度、非同步執行。

在我們的Web中為什麼要使用非同步呢?

目的:快速響應給客戶端,防止客戶端請求等待的。單獨開啟一個執行緒處理。

使用非同步也有缺點:

執行緒安全問題、不能及時拿到結果、消耗CPU

能夠讓耗時的時間,交給單獨執行緒處理 也能夠拿到非同步執行緒結果

本文參考

螞蟻課堂

http://www.mayikt.co