前言 关于SpringMVC初始化ContextLoader中的XMLWebApplicationContext,以及DispatcherServlet初始化等等,这样的原理 已经有N多的前辈和牛人总结过了, 我就不在这里重复轮子了。~
正文 找到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方法,需要在代码中写成如下形式:
Java代码
- 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源码容易降低关注点。
Java代码
- //定义一个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();
- }