springmvc5中设计模式

用了5种设计模式
组合模式
责任链模式
适配器模式
策略模式

组合模式

WebMvcConfigurerComposite体现了组合模式

树枝节点用Composite结尾,里面包含了树叶节点,树枝和树叶都实现了相同的抽象类或接口WebMvcConfigurer

class WebMvcConfigurerComposite implements WebMvcConfigurer {
    private final List<WebMvcConfigurer> delegates = new ArrayList();

    WebMvcConfigurerComposite() {
    }

    public void addWebMvcConfigurers(List<WebMvcConfigurer> configurers) {
        if(!CollectionUtils.isEmpty(configurers)) {
            this.delegates.addAll(configurers);
        }

    }
...
}

责任链模式

DispatcherServlet核心方法doDispatch体现了责任链模式
request是请求,所有入参包含request的方法,都是责任链的体现

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;

        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

        try {
            ModelAndView mv = null;
            Exception dispatchException = null;

            try {
                processedRequest = checkMultipart(request);
                multipartRequestParsed = (processedRequest != request);
                // 获取该请求的handler,每个handler实为HandlerExecutionChain,它为一个处理链,负责处理整个请求
                mappedHandler = getHandler(processedRequest);
                if (mappedHandler == null || mappedHandler.getHandler() == null) {
                    noHandlerFound(processedRequest, response);
                    return;
                }

                HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

                String method = request.getMethod();
                boolean isGet = "GET".equals(method);
                if (isGet || "HEAD".equals(method)) {
                    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                    if (logger.isDebugEnabled()) {
                        logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                    }
                    if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                        return;
                    }
                }
                // 责任链执行预处理方法,实则是将请求交给注册的请求拦截器执行
                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }
                // 实际的执行逻辑的部分,也就是你加了@RequestMapping注解的方法
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }
                applyDefaultViewName(processedRequest, mv);
                // 责任链执行后处理方法,实则是将请求交给注册的请求拦截器执行
                mappedHandler.applyPostHandle(processedRequest, response, mv);
            }
            catch (Exception ex) {
                dispatchException = ex;
            }
            catch (Throwable err) {
                dispatchException = new NestedServletException("Handler dispatch failed", err);
            }
            // 处理返回的结果,触发责任链上注册的拦截器的AfterCompletion方法,其中也用到了HandlerExecutionChain注册的handler来处理错误结果
            processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
        }
        catch (Exception ex) {
            // 触发责任链上注册的拦截器的AfterCompletion方法
            triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
        }
        catch (Throwable err) {
            triggerAfterCompletion(processedRequest, response, mappedHandler,
                    new NestedServletException("Handler processing failed", err));
        }
        finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            }
            else {
                if (multipartRequestParsed) {
                    cleanupMultipart(processedRequest);
                }
            }
        }
    }

适配器模式

适配器模式将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作.它主要分为三类:类适配器模式、对象的适配器模式、接口的适配器模式.
适配器类以Adapter结尾,

但是HandlerAdapter 是接口,不是适配器类

public interface HandlerAdapter {

    /**
     * 判断此handler是否是此HandlerAdapter支持的类型,每种HandlerAdapter只支持一种类型的handler
     */
    boolean supports(Object handler);

    /**
     * 使用所给的handler处理请求
     */
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

    long getLastModified(HttpServletRequest request, Object handler);

}

在这里插入图片描述
HandlerAdapter有五个实现类,其中继承自AbstractHandlerMethodAdapter的RequestMappingHandlerAdapter就是springMVC中处理请求最重要的类之一。

public abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered {

    private int order = Ordered.LOWEST_PRECEDENCE;


    public AbstractHandlerMethodAdapter() {
        // no restriction of HTTP methods by default
        super(false);
    }

    public void setOrder(int order) {
        this.order = order;
    }

    @Override
    public int getOrder() {
        return this.order;
    }


    /**
     * 用instanceof判断此handler是否是HandlerMethod类型
     */
    @Override
    public final boolean supports(Object handler) {
        return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
    }

    /**
     * 判断是否支持此HandlerMethod
     */
    protected abstract boolean supportsInternal(HandlerMethod handlerMethod);

    /**
     * 将handler强转为HandlerMethod传入handleInternal方法
     */
    @Override
    public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        return handleInternal(request, response, (HandlerMethod) handler);
    }

    /**
     * 实际的处理方法,由子类实现,由所给HandlerMethod处理请求
     */
    protected abstract ModelAndView handleInternal(HttpServletRequest request,
            HttpServletResponse response, HandlerMethod handlerMethod) throws Exception;

    @Override
    public final long getLastModified(HttpServletRequest request, Object handler) {
        return getLastModifiedInternal(request, (HandlerMethod) handler);
    }

    protected abstract long getLastModifiedInternal(HttpServletRequest request, HandlerMethod handlerMethod);

}

策略模式

策略模式是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
使用策略模式有时候可以让我们的编码从繁琐难维护的if-else中解放出来。

决定request的media types时也用到了策略模式。其中的ContentNegotiationManager是最核心的一个类

策略接口

@FunctionalInterface
public interface ContentNegotiationStrategy {
    List<MediaType> resolveMediaTypes(NativeWebRequest var1) throws HttpMediaTypeNotAcceptableException;
}

很多实现类,实现具体策略
在这里插入图片描述

ContentNegotiationManager处理类也可以实现策略接口

public class ContentNegotiationManager implements ContentNegotiationStrategy, MediaTypeFileExtensionResolver {
    private static final List<MediaType> MEDIA_TYPE_ALL;
    private final List<ContentNegotiationStrategy> strategies;
    private final Set<MediaTypeFileExtensionResolver> resolvers;

    public ContentNegotiationManager(ContentNegotiationStrategy... strategies) {
        this((Collection)Arrays.asList(strategies));
    }

    public ContentNegotiationManager(Collection<ContentNegotiationStrategy> strategies) {
        this.strategies = new ArrayList();
        this.resolvers = new LinkedHashSet();
        Assert.notEmpty(strategies, "At least one ContentNegotiationStrategy is expected");
        this.strategies.addAll(strategies);
        Iterator var2 = this.strategies.iterator();

        while(var2.hasNext()) {
            ContentNegotiationStrategy strategy = (ContentNegotiationStrategy)var2.next();
            if(strategy instanceof MediaTypeFileExtensionResolver) {
                this.resolvers.add((MediaTypeFileExtensionResolver)strategy);
            }
        }

    }

    public ContentNegotiationManager() {
        this(new ContentNegotiationStrategy[]{new HeaderContentNegotiationStrategy()});
    }

    public List<ContentNegotiationStrategy> getStrategies() {
        return this.strategies;
    }

    public List<MediaType> resolveMediaTypes(NativeWebRequest request) throws HttpMediaTypeNotAcceptableException {
        Iterator var2 = this.strategies.iterator();

        List mediaTypes;
        do {
            if(!var2.hasNext()) {
                return Collections.emptyList();
            }

            ContentNegotiationStrategy strategy = (ContentNegotiationStrategy)var2.next();
            mediaTypes = strategy.resolveMediaTypes(request);
        } while(mediaTypes.isEmpty() || mediaTypes.equals(MEDIA_TYPE_ALL));

        return mediaTypes;
    }

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值