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;
}