用了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 defaultsuper(false);}public void setOrder(int order) {this.order = order;}@Overridepublic int getOrder() {return this.order;}/*** 用instanceof判断此handler是否是HandlerMethod类型*/@Overridepublic final boolean supports(Object handler) {return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));}/*** 判断是否支持此HandlerMethod*/protected abstract boolean supportsInternal(HandlerMethod handlerMethod);/*** 将handler强转为HandlerMethod传入handleInternal方法*/@Overridepublic 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;@Overridepublic 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;}

springmvc5中设计模式相关推荐

  1. java 值对象_java 中设计模式(值对象)的实例详解

    java 中设计模式(值对象)的实例详解 应用场景:在Java开发时,需要来回交换大量的数据,比如要为方法传入参数,也要获取方法的返回值,该如何能更好的进行数据的交互?这个时候就需要用到我们的值对象设 ...

  2. Python如何实现单例模式?其他23中设计模式python如何实现?

    单例模式主要有四种方法:new.共享属性.装饰器.import. # __ new__方法:class Singleton(object):def __new__(cls, *args, **kw): ...

  3. spring aop设计模式_Spring框架中设计模式的运用

    设计模式大家可能随口就能说出总共有23种,但是具体怎么用,或者在常用的组建中有哪些体现,这时候不一定说的上来了.接下来几篇文章,我们一起深入理解.首先我们一起了解下常用的组建中是怎么运用的,比如 JD ...

  4. Java23中设计模式(Design Patterns)详解

    2019独角兽企业重金招聘Python工程师标准>>> 设计模式(Design Patterns) --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复 ...

  5. java中的装饰模式讲解,java 中设计模式(装饰设计模式)的实例详解

    搜索热词 java 中设计模式(装饰设计模式)的实例详解 应用场景: 在不对原有对象类进行修改的基础上,给一个或多个已有的类对象提供增强额外的功能. 我觉得可以从字面理解,装饰,装饰房子.房子可以看成 ...

  6. Tomcat中设计模式

    文章目录 1 Tomcat中设计模式 1.1 门面设计模式 1.1.1 门面设计模式的原理 1.1.2 Tomcat的门面设计模式示例 1.2 观察者设计模式 1.2.1 观察者模式的原理 1.2.2 ...

  7. 三句话巧记23中设计模式

    大家都知道23中设计模式,其中又可以分成三类,创建型模式,结构型模式,行为型模式.但是总是在实际应用中忘记了,当具体看到一些代码的时候也想不起来具体对应的是哪种设计模式,对经常重构的代码人员来说是一个 ...

  8. java中23中设计模式详解

    设计模式(Design Patterns) --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  9. java23中设计模式(1)-facade(门面,外观)模式

    java23中设计模式(1)-facade(门面,外观)模式 写在前面 学习java以来不断听到各种设计模式,各种框架也大量使用模式 面试的时候曾经也被问过关于设计模式的问题,但是一直没有 系统的了解 ...

最新文章

  1. 打造精简版Linux-mini
  2. java bean 工厂模式_Spring框架通过工厂创建Bean的三种方式实现
  3. 【githubgit】1、github中的watch、star、fork的作用
  4. 机器学习-数据科学库(第六天)
  5. C# BackgroundWorker 的使用、封装
  6. C++类的使用(六)—— 判断继承
  7. jar文件与云服务器断开,把jar包放到云服务器
  8. [渝粤教育] 湘潭大学 土力学 参考 资料
  9. 每日一题(19)—— 用变量a给出下面的定义
  10. MyEclipse中搭建spring-boot+mybatis+freemarker框架
  11. C++如何防止头文件被二次编译
  12. 计算机硬件课题,计算机硬件技术基础免试课题.pptx
  13. 道路铺设(NOIP2018)
  14. mysql中计算日期整数差
  15. 【MATLAB imagesc 背景色】
  16. html鼠标悬停效果加边框,js实现鼠标悬浮给图片加边框的方法
  17. Gin+Mysql简单的Restful风格的API
  18. 最新QQ坦白说消息查看发送者
  19. 中国卸扣市场趋势报告、技术动态创新及市场预测
  20. 基于arduino的ESP32 学习笔记(六)LVGL文件系统移植,中文字库和图片显示

热门文章

  1. 【王道考研计算机网络】—速率相关的性能指标
  2. HTML的基本知识(七)——表单的基本知识及案例
  3. HDU - 1272小希的迷宫
  4. 越来越多优秀的老员工辞职,怎么办?
  5. FreeNAS 是什么
  6. 银行理财收益复利还是单利?
  7. 单反相机很久没有更新产品问世了,真的已经被抛弃了吗?
  8. 为什么感觉农村人在城里工作后,大部分都变了?
  9. 贷款买车后,有多少人后悔了?
  10. 私域经济运营能力最关键的三个指标