Spring MVC 适配器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jeikerxiao/article/details/88308784

Demo 下载 Github

适配器设计模式

适配器自然采用了适配器的设计模式。

适配器模式:将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作。

适配器模式的别名为包装器(Wrapper)模式,它既可以作为类结构型模式,也可以作为对象结构型模式。

适配器模式包含一下三个角色:

  1. Target(目标抽象类):目标抽象类定义客户所需的接口,可以是一个抽象类或接口,也可以是具体类。

  2. Adapter(适配器类):它可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配。它是适配器模式的核心。

  3. Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类包好了客户希望的业务方法。

适配器示例

1.Controller(handler)

编写一个Controller接口,然后编写三个Controller的实现:

  1. HttpController
  2. SimpleController
  3. AnnotationController
/**
 * Description: 控制器接口
 */
public interface Controller {

}
/**
 * Description: Controller 实现之1:HttpController
 */
public class HttpController implements Controller {

    public void doHttpHandler() {
        System.out.println("HttpController:httpMethod()");
    }
}

/**
 * Description: Controller 实现之2:SimpleController
 */
public class SimpleController implements Controller {

    public void doSimplerHandler() {
        System.out.println("SimpleController:simpleMethod()");
    }
}
/**
 * Description: Controller 实现之3:HttpController
 */
public class AnnotationController implements Controller {

    public void doAnnotationHandler() {
        System.out.println("AnnotationController:annotationMethod()");
    }
}

2.Controller对应的适配器

编写一个HandlerAdapter接口,然后编写三个HandlerAdapter的实现,分别与三个Controller一一对应:

  1. HttpHandlerAdapter
  2. SimpleHandlerAdapter
  3. AnnotationHandlerAdapter

/**
 * Description: 定义一个Adapter接口
 */
public interface HandlerAdapter {

    /**
     * 是否支持
     *
     * @param handler
     * @return
     */
    boolean supports(Object handler);

    /**
     * 处理
     *
     * @param handler
     */
    void handle(Object handler);

}
/**
 * Description: HttpController 的适配器
 */
public class HttpHandlerAdapter implements HandlerAdapter {

    public boolean supports(Object handler) {
        return (handler instanceof HttpController);
    }

    public void handle(Object handler) {
        ((HttpController) handler).doHttpHandler();
    }
}

/**
 * Description: SimpleController的适配器
 */
public class SimpleHandlerAdapter implements HandlerAdapter {

    public boolean supports(Object handler) {
        return (handler instanceof SimpleController);
    }

    public void handle(Object handler) {
        ((SimpleController) handler).doSimplerHandler();
    }
}
/**
 * Description: AnnotationController 的适配器
 */
public class AnnotationHandlerAdapter implements HandlerAdapter {

    public boolean supports(Object handler) {
        return (handler instanceof AnnotationController);
    }

    public void handle(Object handler) {
        ((AnnotationController) handler).doAnnotationHandler();
    }
}

3.模拟DispatchServlet调用

模拟一个DispatcherServlet,来调用HandlerAdapter(适配器类) 作为适配器来适配各种 Handler(适配者类)(如Controller),进而执行Controller中对应的方法。


/**
 * Description: 模拟一个DispatcherServlet,适配器(适配者模式)
 *              HandlerAdapter(适配器类) 作为适配器来适配各种 Handler(适配者类)(如Controller)
 */
public class DispatchServlet {

    public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();

    /**
     * 注册所有 HandlerAdapter
     */
    public DispatchServlet() {
        handlerAdapters.add(new AnnotationHandlerAdapter());
        handlerAdapters.add(new HttpHandlerAdapter());
        handlerAdapters.add(new SimpleHandlerAdapter());
    }

    /**
     * 模拟DispatchServlet 中的 doDispatch()方法
     */
    public void doDispatch() {

        // 此处模拟 SpringMVC 从 mappedHandler 中取 handler 的对象(Controller)
        // 不论实现何种Controller,适配器总能经过适配以后得到想要的结果
        Controller controller1 = new HttpController();
        Controller controller2 = new AnnotationController();
        Controller controller3 = new SimpleController();

        Controller handler = controller2;
        // 通过handler来找到对应适配器
        HandlerAdapter handlerAdapter = getHandler(handler);
        // 通过执行适配器的handle,来执行对应的controller对应方法
        handlerAdapter.handle(handler);
    }

    /**
     * 找到与handler适配的适配器:通过handler 遍历 HandlerAdapter 适配器来实现
     */
    public HandlerAdapter getHandler(Controller handler) {
        for (HandlerAdapter adapter : handlerAdapters) {
            if (adapter.supports(handler)) {
                return adapter;
            }
        }
        return null;
    }

    /**
     * 模拟运行
     */
    public static void main(String[] args) {
        new DispatchServlet().doDispatch();
    }
}

Spring MVC 源码分析HandlerAdapter

1.查看Controller接口

@FunctionalInterface
public interface Controller {

	 /**
	  * 处理request 请求,并返回 ModelAndView 对象
	  */
	@Nullable
	ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;

}

查看Controller的实现

在这里插入图片描述

2.查看HandlerAdapter接口

public interface HandlerAdapter {

	/**
	 * 传入handler,查看是否有对应的HandlerAdapter与之匹配。
	 */
	boolean supports(Object handler);

	/**
	 * 使用传入的handler 处理这个request请求,并返回ModelAndView对象
	 */
	@Nullable
	ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

	long getLastModified(HttpServletRequest request, Object handler);
}

查看HandlerAdapter的实现

在这里插入图片描述

3.DispatcherServlet中doDispatch()方法

查看分析DispatcherServlet.classdoDispatch()方法

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {

	··· ···

	try {
		... ...

		try {
			... ...

			// Determine handler for the current request.
			// 1.为当前请求查找Controller对应的方法,如找到示例中的UserController.hello()方法
			mappedHandler = getHandler(processedRequest);
			
			... ...
			
			// Determine handler adapter for the current request.
			// 2.确定对应Handler的执行链,在此处决定HandlerExecutionChain,
			// 也就是决定URL对应要执行的拦截器和Handler
			HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

			... ...

			// Actually invoke the handler.
			// 3.实际调用Controller对应Handler并执行,如执行示例中的UserController.hello()方法
			mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

			... ...
		}
		... ...
	}
	... ...
}

关注第2点,通过Handler获取对应的HandlerAdapter的方法

protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
	if (this.handlerAdapters != null) {
		// 遍历HandlerAdapter,找到支持当前handler的HandlerAdapter
		for (HandlerAdapter adapter : this.handlerAdapters) {
			if (adapter.supports(handler)) {
				return adapter;
			}
		}
	}
	... ...
}

猜你喜欢

转载自blog.csdn.net/jeikerxiao/article/details/88308784