成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

聊一聊適配器模式在Spring框架中的應用

開發 前端
適配器模式(Adapter Pattern)是一種結構型設計模式,它允許不兼容的接口之間能夠協同工作。在Spring框架中,適配器模式被廣泛應用,特別是在Spring MVC的請求處理機制中。

一、什么是適配器模式

適配器模式(Adapter Pattern)是一種結構型設計模式,它允許不兼容的接口之間能夠協同工作。在Spring框架中,適配器模式被廣泛應用,特別是在Spring MVC的請求處理機制中。

適配器模式主要分為兩種:

  • 類適配器:通過繼承來實現適配
  • 對象適配器:通過組合來實現適配

Spring主要采用的是對象適配器模式,因為它更靈活且符合組合優于繼承的原則。

二、Spring MVC中的HandlerAdapter

Spring MVC中,處理器(Handler)可以有多種形式:

  • 基于注解的@Controller
  • 實現Controller接口的類
  • 實現HttpRequestHandler接口的類
  • 其他自定義處理器

這些處理器的接口各不相同,DispatcherServlet如果直接與這些處理器交互,會導致代碼高度耦合且難以維護。HandlerAdapter的出現解決了這個問題,它提供了一個統一的接口,使得DispatcherServlet可以用統一的方式調用各種處理器。

HandlerAdapter源碼:

public interface HandlerAdapter {
    boolean supports(Object handler);


    @Nullable
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;


    long getLastModified(HttpServletRequest request, Object handler);
}
  • supports():判斷是否支持給定的處理器
  • handle():實際處理請求并返回ModelAndView
  • getLastModified():獲取資源的最后修改時間(用于緩存)

三、Spring中主要HandlerAdapter實現

31. RequestMappingHandlerAdapter

這是處理基于注解的控制器(@Controller)的適配器,也是最常用的適配器。

使用示例:

@Controller
public class UserController {


    @GetMapping("/user/{id}")
    public String getUser(@PathVariable Long id, Model model) {
        User user = userService.getUserById(id);
        model.addAttribute("user", user);
        return "userDetail";
    }
}

RequestMappingHandlerAdapter源碼分析:

public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
        implements BeanFactoryAware, InitializingBean {


    // 支持的方法參數解析器
    private List<HandlerMethodArgumentResolver> argumentResolvers;


    // 支持的方法返回值處理器
    private List<HandlerMethodReturnValueHandler> returnValueHandlers;


    @Override
    protected boolean supportsInternal(HandlerMethod handlerMethod) {
        return true;
    }


    @Override
    protected ModelAndView handleInternal(HttpServletRequest request,
            HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {


        // 1. 準備處理請求
        checkRequest(request);


        // 2. 執行處理器方法
        ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
        invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
        invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);


        // 3. 處理結果并返回ModelAndView
        // ... 詳細處理邏輯
    }
}

處理流程:

  1. 通過supports()確認支持該處理器
  2. 解析方法參數(使用argumentResolvers)
  • 解析@PathVariable
  • 注入Model參數
  1. 調用目標方法
  2. 處理返回值(使用returnValueHandlers)
  • 處理String類型的視圖名
  • 處理Model屬性

3.2 SimpleControllerHandlerAdapter

這是處理實現了Controller接口的傳統控制器的適配器。

使用示例:

public class LegacyUserController implements Controller {


    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Long id = Long.parseLong(request.getParameter("id"));
        User user = userService.getUserById(id);
        return new ModelAndView("userDetail", "user", user);
    }
}

SimpleControllerHandlerAdapter的源碼分析:

public class SimpleControllerHandlerAdapter implements HandlerAdapter {


    @Override
    public boolean supports(Object handler) {
        return (handler instanceof Controller);
    }


    @Override
    @Nullable
    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {


        return ((Controller) handler).handleRequest(request, response);
    }


    @Override
    public long getLastModified(HttpServletRequest request, Object handler) {
        if (handler instanceof LastModified) {
            return ((LastModified) handler).getLastModified(request);
        }
        return -1L;
    }
}

3.3 HttpRequestHandlerAdapter

這是處理HttpRequestHandler接口實現的適配器,通常用于處理HTTP請求的原始形式。

使用示例:

public class ResourceHttpRequestHandler implements HttpRequestHandler {


    @Override
    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 直接操作response輸出資源
        Path path = Paths.get("static", request.getPathInfo());
        Files.copy(path, response.getOutputStream());
    }
}

HttpRequestHandlerAdapter的源碼分析:

public class HttpRequestHandlerAdapter implements HandlerAdapter {


    @Override
    public boolean supports(Object handler) {
        return (handler instanceof HttpRequestHandler);
    }


    @Override
    @Nullable
    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {


        ((HttpRequestHandler) handler).handleRequest(request, response);
        return null;
    }


    @Override
    public long getLastModified(HttpServletRequest request, Object handler) {
        if (handler instanceof LastModified) {
            return ((LastModified) handler).getLastModified(request);
        }
        return -1L;
    }
}

四、HandlerAdapter的注冊與使用流程

4.1 初始化過程

在Spring MVC中,HandlerAdapter通常通過WebMvcConfigurer配置:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {


    @Override
    public void configureHandlerAdapters(HandlerAdapterRegistry registry) {
        registry.addAdapter(new RequestMappingHandlerAdapter());
        registry.addAdapter(new SimpleControllerHandlerAdapter());
        registry.addAdapter(new HttpRequestHandlerAdapter());
    }
}

4.2 DispatcherServlet的處理流程

讓我們看看DispatcherServlet如何利用HandlerAdapter處理請求:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 1. 獲取處理器
    HandlerExecutionChain mappedHandler = getHandler(request);


    // 2. 獲取適配器
    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());


    // 3. 執行前置攔截器
    if (!mappedHandler.applyPreHandle(request, response)) {
        return;
    }


    // 4. 實際處理請求
    ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler());


    // 5. 應用默認視圖名
    applyDefaultViewName(request, mv);


    // 6. 執行后置攔截器
    mappedHandler.applyPostHandle(request, response, mv);


    // 7. 處理結果
    processDispatchResult(request, response, mappedHandler, mv, dispatchException);
}

getHandlerAdapter()方法的實現:

protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
    for (HandlerAdapter adapter : this.handlerAdapters) {
        if (adapter.supports(handler)) {
            return adapter;
        }
    }
    throw new ServletException("No adapter for handler [" + handler + "]");
}


圖片圖片


責任編輯:武曉燕 來源: 全棧程序員老馬
相關推薦

2021-02-16 08:16:09

適配器模式MybatisJava

2025-06-03 04:00:00

Spring框架配置

2016-01-15 09:51:27

AngularJS實際應用

2018-10-11 10:38:31

前端JavaScript編程語言

2022-11-26 00:00:06

裝飾者模式Component

2023-05-15 08:38:58

模板方法模式

2022-11-01 08:46:20

責任鏈模式對象

2020-10-25 08:56:21

適配器模式

2020-07-16 14:40:23

大數據計算框架

2024-02-22 12:13:49

適配器模式代碼

2022-02-13 23:33:24

設計模式Java

2013-11-26 16:39:21

Android設計模式

2021-02-18 08:39:28

設計模式場景

2012-05-16 17:22:11

Java設計模式

2019-07-01 14:55:44

應用安全web安全滲透測試

2022-02-18 17:21:29

適配器模式客戶端

2023-12-28 09:59:37

Spring容器XML

2012-09-19 15:29:26

Worklight適配器

2020-12-11 11:11:44

原子類JavaCAS

2019-12-02 16:23:03

Python編程語言“垃圾”回收
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲二区在线观看 | 日本不卡免费新一二三区 | 99精品国产一区二区三区 | 91伊人| 日韩欧美三级电影在线观看 | av在线免费观看网站 | 天天躁日日躁狠狠躁2018小说 | 亚洲欧洲成人av每日更新 | 国产精品亚洲精品日韩已方 | 中国一级特黄毛片大片 | 日本不卡免费新一二三区 | 亚洲一区免费在线 | 亚洲高清av | 青青草一区 | 久久亚洲欧美日韩精品专区 | 日韩国产精品一区二区三区 | 涩涩视频网 | 亚洲一卡二卡 | 欧美日韩精品一区 | 国内精品久久久久久久 | 国产资源在线视频 | 欧美激情一区二区三区 | 日韩成人在线网站 | 欧美精品一区二区三区在线播放 | 亚洲视频免费 | 黄色精品 | 亚洲成人av | 91热爆在线观看 | 黄视频网站免费观看 | 亚洲444eee在线观看 | 久久精品国产久精国产 | 久久一区二区视频 | 99热视 | 日韩中文电影 | 亚洲在线一区二区 | 日韩精品成人免费观看视频 | 最新黄色在线观看 | 欧美在线一区二区三区 | 国产一区二区精品在线观看 | 亚洲高清视频一区二区 | 另类视频区 |