用了5種設計模式
組合模式
責任鏈模式
適配器模式
策略模式
WebMvcConfigurerComposite體現了組合模式
Spring mvc,樹枝節點用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結尾,
springmvc教程,但是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中解放出來。
java spring mvc?決定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;}
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态