前言 關於SpringMVC初始化ContextLoader中的XMLWebApplicationContext,以及DispatcherServlet初始化等等,這樣的原理 已經有N多的前輩和牛人總結過了, 我就不在這里重復輪子了。~
正文 找到DispatcherServlet類中的doDispatch體,我們可以看到,它的作用是相當於在Servlet的 doService調用的。 也就是用來傳遞request給我們編寫的Controller並執行相應的方法、返回ModeView對象。
執行的代碼片段:
此處采用了適配器模式, 由於Controller的類型不同,有多重實現方式,那么調用方式就不是確定的,如果需要直接調用Controller方法,需要在代碼中寫成如下形式:
因此Spring定義了一個適配接口,使得每一種Controller有一種對應的適配器實現類, 讓適配器代替controller執行相應的方法。這樣在擴展Controller 時,只需要增加一個適配器類就完成了SpringMVC的擴展了,真的是很精巧的做法!
廢話不多說還是上代碼吧,為了看得清楚,就自己實現一套代碼來模擬springMVC, 直接貼Spring源碼容易降低關注點。
正文 找到DispatcherServlet類中的doDispatch體,我們可以看到,它的作用是相當於在Servlet的 doService調用的。 也就是用來傳遞request給我們編寫的Controller並執行相應的方法、返回ModeView對象。
執行的代碼片段:
- ...
- HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
- mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
- ...
... HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); ...mappedHandler.getHandler()得到的是Controller對象 而此處並非采用直接 調用.handlerRequest或者MultiActionController中編寫的自定義方法,而采用了一個HandlerAdapter 的接口。
此處采用了適配器模式, 由於Controller的類型不同,有多重實現方式,那么調用方式就不是確定的,如果需要直接調用Controller方法,需要在代碼中寫成如下形式:
- if(mappedHandler.getHandler() instanceof MultiActionController){
- ((MultiActionController)mappedHandler.getHandler()).xxx
- }else if(mappedHandler.getHandler() instanceof XXX){
- ...
- }else if(...){
- ...
- }
- ...
if(mappedHandler.getHandler() instanceof MultiActionController){ ((MultiActionController)mappedHandler.getHandler()).xxx }else if(mappedHandler.getHandler() instanceof XXX){ ... }else if(...){ ... } ...這樣假設如果我們增加一個HardController,就要在代碼中加入一行 if(mappedHandler.getHandler() instanceof HardController) 這種形式就使得程序難以維護,也違反了設計模式中的開閉原則 -- 對擴展開放,對修改關閉。
因此Spring定義了一個適配接口,使得每一種Controller有一種對應的適配器實現類, 讓適配器代替controller執行相應的方法。這樣在擴展Controller 時,只需要增加一個適配器類就完成了SpringMVC的擴展了,真的是很精巧的做法!
廢話不多說還是上代碼吧,為了看得清楚,就自己實現一套代碼來模擬springMVC, 直接貼Spring源碼容易降低關注點。
- //定義一個Adapter接口
- public interface HandlerAdapter {
- public boolean supports(Object handler);
- public void handle(Object handler);
- }
- //以下是三種Controller實現
- public interface Controller {
- }
- public class HttpController implements Controller{
- public void doHttpHandler(){
- System.out.println("http...");
- }
- }
- public class SimpleController implements Controller{
- public void doSimplerHandler(){
- System.out.println("simple...");
- }
- }
- public class AnnotationController implements Controller{
- public void doAnnotationHandler(){
- System.out.println("annotation...");
- }
- }
- //下面編寫適配器類
- public class SimpleHandlerAdapter implements HandlerAdapter {
- public void handle(Object handler) {
- ((SimpleController)handler).doSimplerHandler();
- }
- public boolean supports(Object handler) {
- return (handler instanceof SimpleController);
- }
- }
- public class HttpHandlerAdapter implements HandlerAdapter {
- public void handle(Object handler) {
- ((HttpController)handler).doHttpHandler();
- }
- public boolean supports(Object handler) {
- return (handler instanceof HttpController);
- }
- }
- public class AnnotationHandlerAdapter implements HandlerAdapter {
- public void handle(Object handler) {
- ((AnnotationController)handler).doAnnotationHandler();
- }
- public boolean supports(Object handler) {
- return (handler instanceof AnnotationController);
- }
- }
- //模擬一個DispatcherServlet
- import java.util.ArrayList;
- import java.util.List;
- public class DispatchServlet {
- public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();
- public DispatchServlet(){
- handlerAdapters.add(new AnnotationHandlerAdapter());
- handlerAdapters.add(new HttpHandlerAdapter());
- handlerAdapters.add(new SimpleHandlerAdapter());
- }
- public void doDispatch(){
- //此處模擬SpringMVC從request取handler的對象,僅僅new出,可以出,
- //不論實現何種Controller,適配器總能經過適配以后得到想要的結果
- // HttpController controller = new HttpController();
- // AnnotationController controller = new AnnotationController();
- SimpleController controller = new SimpleController();
- //得到對應適配器
- HandlerAdapter adapter = getHandler(controller);
- //通過適配器執行對應的controller對應方法
- adapter.handle(controller);
- }
- public HandlerAdapter getHandler(Controller controller){
- for(HandlerAdapter adapter: this.handlerAdapters){
- if(adapter.supports(controller)){
- return adapter;
- }
- }
- return null;
- }
- public static void main(String[] args){
- new DispatchServlet().doDispatch();
- }