一 提出問題
適配器模式在springmvc中的一次經(jīng)典使用體現(xiàn)在它的核心方法doDispatch方法中,我們來看代碼(注:這里只摘錄部分代碼):
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
....... ......
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); //mark1
...... .......
mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); //mark2
...... ......
}
我們先不想適配器模式是什么,都有哪些角色,這些角色在本次使用中的對應(yīng)關(guān)系是什么,我們就只單純的看代碼;mark1處的代碼是通過Handler來獲取HandlerAdapter的過程,mark2處的代碼是使用HandlerAdapter處理請求的過程;那么問題來了,為什么不直接使用Handler來處理我們的請求,卻要把Handler包裝成HandlerAdapter,然后使用后者來處理呢,這不是多此一舉嗎?
二 解答問題
1、首先我們來看這個適配器接口(HandlerAdapter )的實現(xiàn)類

接下來我們?nèi)蓚€具有代表性的來說明我們今天的問題:
public class HttpRequestHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof HttpRequestHandler);
}
@Override
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
((HttpRequestHandler) handler).handleRequest(request, response);
return null;
}
@Override
public long getLastModified(HttpServletRequest request, Object handler) {
if (handler instanceof LastModified) {
return ((LastModified) handler).getLastModified(request);
}
return -1L;
}
}
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;
}
}
現(xiàn)在問題的答案就很明顯了,我們可以看到HttpRequestHandlerAdapter 中包裝的Handler是HttpRequestHandler類型的,SimpleServletHandlerAdapter 中包裝的Handler是Servlet類型的;前者的處理方法是handleRequest,后者的處理方法是service;所以假如在doDispatch中直接用Handler來處理我們的請求,方法名就做不到統(tǒng)一;這也從側(cè)面提示了我們,假如以后有新的handler進來,我們只需要實現(xiàn)一個HandlerAdapter即可,而不需要改動doDispatch中的任何代碼。
(彩蛋:所有的HandlerAdapter在spring容器啟動的時候就已經(jīng)是初始化好的,至于HandlerAdapter是怎樣注入到spring容器中的,就要使用到spring IOC的知識了;這也從側(cè)面說明了學(xué)習(xí)springmvc,spring是基礎(chǔ) )
三 適配器模式
1、首先我們來看下適配器模式的三個角色(摘自《設(shè)計模式之禪》)

現(xiàn)在我們來看下這三種角色在我們今天使用中的對應(yīng):
