第七章 适配器模式 Adapter

结构型设计模式

定义:

  将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间

类图:

  

 

 应用:

  SpringMVC中的适配器模式,在SpringMVC中,使用DispatcherSevlet拦截所有请求,再根据不同的uri调用对应的服务方法。DispatcherSevlet中最核心的doDispatch()方法,截取一段分发服务的代码,这里就用到了适配器模式

  

复制代码
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    ...
        try {
            ModelAndView mv = null;
            Exception dispatchException = null;

            try {
                processedRequest = checkMultipart(request);
                multipartRequestParsed = (processedRequest != request);

                // Determine handler for the current request.
                mappedHandler = getHandler(processedRequest);
                if (mappedHandler == null) {
                    noHandlerFound(processedRequest, response);
                    return;
                }

                // Determine handler adapter for the current request.
                HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

                // Process last-modified header, if supported by the handler.
                String method = request.getMethod();
                boolean isGet = HttpMethod.GET.matches(method);
                if (isGet || HttpMethod.HEAD.matches(method)) {
                    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                    if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                        return;
                    }
                }

                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }

                // Actually invoke the handler.
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }
    ...
    }
复制代码

  首先我们来看这个适配器接口(HandlerAdapter )

public interface HandlerAdapter {
    boolean supports(Object var1);

    @Nullable
    ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;

    long getLastModified(HttpServletRequest var1, Object var2);
}

  HandlerAdapter接口约束了他的子类必须实现的三个方法,判断是否支持这个handler,执行handler并返回ModelAndView对象,获取最近一次修改时间。很明显这个HandlerAdapter就是为了针对不同的服务实现返回同样的视图。这里,需要了解一下SpringMVC中有多少种服务的实现方式,看一下下面的实现类:

  最典型的三个:

  1. 使用@RequestMapping修饰的方法。这里就是使用RequestMappingHandlerAdapter,去处理这个服务请求,想知道细节的可以去源码看
  2. 实现了Servlet接口。这里就是使用SimpleServletHandlerAdapter
复制代码
public class SimpleServletHandlerAdapter implements HandlerAdapter {

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

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

        ((Servlet) handler).service(request, response);
        return null;
    }

    @Override
    public long getLastModified(HttpServletRequest request, Object handler) {
        return -1;
    }

}
复制代码
  1. 实现了Controller接口
    这里就是使用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;
    }

}
复制代码

 

Java I/O中适配器模式:

InputStreamReader/OutputStreamWriter

posted on   胡子就不刮  阅读(74)  评论(0编辑  收藏  举报

编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示