找到DispatcherServlet类中的`doDispatch`体,我们可以看到,它的作用是相当于在Servlet的 doService调用的。 也就是用来传递request给我们编写的Controller并执行相应的方法、返回ModeView对象。
执行的代码片段:
|
|
mappedHandler.getHandler()
得到的是Controller对象
而此处并非采用直接 调用.handlerRequest或者MultiActionController中编写的自定义方法,而采用了一个HandlerAdapter
的接口。
此处采用了适配器模式, 由于Controller的类型不同,有多重实现方式,那么调用方式就不是确定的,如果需要直接调用Controller方法,需要在代码中写成如下形式:
|
|
这样假设如果我们增加一个HardController,就要在代码中加入一行 if(mappedHandler.getHandler() instanceof HardController) , 这种形式就使得程序难以维护,也违反了设计模式中的开闭原则
– 对扩展开放,对修改关闭。
因此Spring定义了一个适配接口,使得每一种Controller有一种对应的适配器实现类, 让适配器代替controller执行相应的方法。这样在扩展Controller 时,只需要增加一个适配器类就完成了SpringMVC的扩展了.
实现一套代码来模拟springMVC:
|
|
|
|
|
|
|
|
Spring MVC HandlerAdapter ,有下面几个子类:
这几个子类,分别用于适配不同的Handler(我们写的请求处理代码)。
如果Handler是一个简单的Servlet(这是在web.xml配置自定义的Servlet时的方式),那么就使用SimpleServletHandlerAdapter
|
|
如果Handler是一个简单的Controller的实例,就是用SimpleControllerHandlerAdapter
来适配(在Spring2.5时,一般会采用这种方式):
|
|
如果使用了注解方式,就使用AnnotationMethodHandlerAdapter
.
从上面的可以采用的几种处理HttpRequest的写法上来看,这几种Handler分别属于不同的类,也就是处理的接口是不同的。然而在DispatcherServlet中,只用了一个接口,采用了适配器模式,来屏蔽掉这种差异,在适配器的内部,进行接口的转换工作。