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

聊一聊適配器模式在Spring框架中的應(yīng)用

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

一、什么是適配器模式

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

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

  • 類適配器:通過繼承來實現(xiàn)適配
  • 對象適配器:通過組合來實現(xiàn)適配

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

二、Spring MVC中的HandlerAdapter

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

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

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

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實現(xiàn)

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 {


    // 支持的方法參數(shù)解析器
    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. 執(zhí)行處理器方法
        ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
        invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
        invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);


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

處理流程:

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

3.2 SimpleControllerHandlerAdapter

這是處理實現(xiàn)了Controller接口的傳統(tǒng)控制器的適配器。

使用示例:

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接口實現(xiàn)的適配器,通常用于處理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. 執(zhí)行前置攔截器
    if (!mappedHandler.applyPreHandle(request, response)) {
        return;
    }


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


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


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


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

getHandlerAdapter()方法的實現(xiàn):

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 + "]");
}


圖片圖片


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

2021-02-16 08:16:09

適配器模式MybatisJava

2025-06-03 04:00:00

Spring框架配置

2016-01-15 09:51:27

AngularJS實際應(yīng)用

2023-05-15 08:38:58

模板方法模式

2022-11-01 08:46:20

責任鏈模式對象

2018-10-11 10:38:31

前端JavaScript編程語言

2022-11-26 00:00:06

裝飾者模式Component

2020-10-25 08:56:21

適配器模式

2020-07-16 14:40:23

大數(shù)據(jù)計算框架

2024-02-22 12:13:49

適配器模式代碼

2022-02-13 23:33:24

設(shè)計模式Java

2012-05-16 17:22:11

Java設(shè)計模式

2021-02-18 08:39:28

設(shè)計模式場景

2013-11-26 16:39:21

Android設(shè)計模式

2019-07-01 14:55:44

應(yīng)用安全web安全滲透測試

2023-12-28 09:59:37

Spring容器XML

2022-02-18 17:21:29

適配器模式客戶端

2020-12-11 11:11:44

原子類JavaCAS

2019-12-02 16:23:03

Python編程語言“垃圾”回收

2022-08-30 07:39:57

C++namespace隔離
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 在线免费观看a级片 | 蜜桃视频在线观看免费视频网站www | 国产精品久久久久久久久久久新郎 | 国产一级片精品 | 亚洲图片视频一区 | 欧美精品一区在线发布 | 黄色av网站免费看 | 亚洲一区 | 亚洲精品日韩综合观看成人91 | 久久久国产一区二区三区 | 国产日韩欧美在线播放 | 91精品在线播放 | 国产亚洲精品美女久久久久久久久久 | 青青草网站在线观看 | 日韩av一二三区 | 九九综合九九 | 国产一区成人 | 色眯眯视频在线观看 | 亚洲欧美国产精品一区二区 | 国产小u女发育末成年 | 特级a欧美做爰片毛片 | 91资源在线 | 国产视频2021 | 日韩精品二区 | 久久久久久久久99 | 午夜在线视频一区二区三区 | 午夜精品一区二区三区在线视频 | 午夜精品视频一区 | 亚洲视频中文字幕 | 免费看黄色视屏 | www.日韩免费 | 欧美日本在线观看 | 伊人91在线 | 国产精品综合视频 | 99国产精品99久久久久久 | 国产精品久久久久久久白浊 | 狠狠干影院 | 亚洲国产一区二区三区在线观看 | 日韩精品一区二区三区四区视频 | 爱操av| 精久久久 |