使用HandlerAdapter 的原因分析: 可以看到处理器的类型不同,有多重实现方式,那么调用方式就不是确定的,如果需要直接调用 Controller方法,需要调用的时候就得不断是使用if else来进行判断是哪一种子类然后执行。那么 如果后面要扩展Controller,就得修改原来的代码,这样违背了OCP原则。原码 ( DispatcherServlet中)
doDispatch方法
getHandlerAdapter方法获取handler对应的HandlerAdapter(适配器),需要进行匹配的
supports方法(判断当前传入的handler是否与当前HandlerAdapter适配的是同一个实例(类型))
执行方法,返回MondelAndView
动手写SpringMVC通过
适配器设计模式获取到对应的Controller的源码
UML类图
代码示例
//多种Controller实现
public interface Controller {}
class HttpController implements Controller {
public void doHttpHandler() {
System.out.println("http...");
}
}
class SimpleController implements Controller {
public void doSimplerHandler() {
System.out.println("simple...");
}
}
class AnnotationController implements Controller {
public void doAnnotationHandler() {
System.out.println("annotation...");
}
}
//-------------------------------------------------------------------------
//定义一个Adapter接口 适 配器抽象层
public interface HandlerAdapter {
boolean supports(Object handler);
void handle(Object handler);
}
// 多种适配器类/实现
class SimpleHandlerAdapter implements HandlerAdapter {
@Override
public void handle(Object handler) {
//强转SimpleController类型,调用该类的.doSimplerHandler()方法
((SimpleController) handler).doSimplerHandler();
}
@Override
public boolean supports(Object handler) {
//判断传入的handler是否是SimpleController实例/类型的,即返回true/false
return (handler instanceof SimpleController);
}
}
class HttpHandlerAdapter implements HandlerAdapter {
@Override
public void handle(Object handler) {
((HttpController) handler).doHttpHandler();
}
@Override
public boolean supports(Object handler) {
return (handler instanceof HttpController);
}
}
class AnnotationHandlerAdapter implements HandlerAdapter {
@Override
public void handle(Object handler) {
((AnnotationController) handler).doAnnotationHandler();
}
@Override
public boolean supports(Object handler) {
return (handler instanceof AnnotationController);
}
}
//-------------------------------------------------------------------------
//调用方/测试
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的对象,
// 适配器可以获取到希望的Controller
//HttpController controller = new HttpController();
AnnotationController controller = new AnnotationController();
//SimpleController controller = new SimpleController();
// 根据controller 得到对应适配器
HandlerAdapter adapter = getHandler(controller);
// 通过适配器执行对应的controller对应方法
adapter.handle(controller);
}
public HandlerAdapter getHandler(Controller controller) {
//遍历:根据得到的controller(handler), 返回对应适配器
for (HandlerAdapter adapter : handlerAdapters) {
if (adapter.supports(controller)) {
return adapter;
}
}
return null;
}
//主方法
public static void main(String[] args) {
new DispatchServlet().doDispatch(); //annotation...
}
}
适配器模式的注意事项和细节
三种命名方式,是根据 src(被适配者)是以怎样的形式给到Adapter(在Adapter里的形式)来命名的。
类适配器:以类给到,在Adapter里,就是将src当做类,继承
对象适配器:以对象给到,在Adapter里,将src作为一个对象,持有
接口适配器:以接口给到,在Adapter里,将src作为一个接口,实现
Adapter模式最大的作用还是将原本不兼容的接口融合在一起工作。
实际开发中,实现起来不拘泥于我们讲解的三种经典形式
桥接模式
应用案例