【走近Spring】Spring MVC容器的web九大组件之---HandlerMapping源码详解
作者:互联网
在 Spring MVC容器启动时——web九大组件初始化 已经大概介绍过web九大组件,本文将聚焦于Spring MVC中最重要的一个组件:HandlerMapping展开讨论。
HandlerMapping
用来查找Handler的。在SpringMVC中会有很多请求,每个请求都需要一个Handler处理,具体接收到一个请求之后使用哪个Handler进行处理呢?这就是HandlerMapping需要做的事。
HandlerMapping:负责映射用户的URL和对应的处理类Handler,HandlerMapping并没有规定这个URL与应用的处理类如何映射。所以在HandlerMapping接口中仅仅定义了根据一个URL必须返回一个由HandlerExecutionChain代表的处理链,我们可以在这个处理链中添加任意的HandlerAdapter实例来处理这个URL对应的请求(这样保证了最大的灵活性映射关系)。
public interface HandlerMapping {
//@since 4.3.21
String BEST_MATCHING_HANDLER_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingHandler";
String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping.class.getName() + ".pathWithinHandlerMapping";
String BEST_MATCHING_PATTERN_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingPattern";
String INTROSPECT_TYPE_LEVEL_MAPPING = HandlerMapping.class.getName() + ".introspectTypeLevelMapping";
String URI_TEMPLATE_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".uriTemplateVariables";
String MATRIX_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".matrixVariables";
String PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE = HandlerMapping.class.getName() + ".producibleMediaTypes";
// 该接口提供的唯一一个方法~~~~
@Nullable
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}
看看它的继承树:
它有两大继承主线:MatchableHandlerMapping和AbstractHandlerMapping。
AbstractHandlerMapping
这是Spring的常用模式了,一言不合就先来个抽象实现。查看它的继承图谱:
有必要先对两个XXXSupport进行一个非常简单的说明~
WebApplicationObjectSupport和ApplicationObjectSupport
看它们的声明,它们更像是ApplicationContextAware和ServletContextAware的适配器。
public abstract class ApplicationObjectSupport implements ApplicationContextAware { ... }
public abstract class WebApplicationObjectSupport extends ApplicationObjectSupport implements ServletContextAware { ... }
所以如果我们在继承允许的情况下,只需要继承此类就能自动拥有上面两个接口的功能了。
@Service
public class HelloServiceImpl extends WebApplicationObjectSupport implements HelloService {
@Override
public Object hello() {
// 继承自ApplicationObjectSupport就可以很方便的获取到下面这两个值
System.out.println(super.getApplicationContext());
System.out.println(super.obtainApplicationContext()); //@since 5.0
// MessageSourceAccessor参考:MessageSourceAware 它是对MessageSource的一个包装 处理国际化
System.out.println(super.getMessageSourceAccessor());
// 这里需要继承和web相关的:WebApplicationObjectSupport
System.out.println(super.getWebApplicationContext());
System.out.println(super.getServletContext());
System.out.println(super.getTempDir()); //Tomcat9_demowar\work\Catalina\localhost\demo_war_war
return "service hello";
}
@Override
protected void initApplicationContext() throws BeansException {
// 这是父类提供给子类的(父类为空实现~),子类可以自行实现,实现子类的逻辑
// 比如子类AbstractDetectingUrlHandlerMapping就复写了此方法去detectHandlers();
super.initApplicationContext();
}
}
就这样可以通过继承的方式快速的实现获取上下文等,推荐使用~~~
WebApplicationObjectSupport用于提供上下文ApplicationContext和ServletContext的功能~
很显然如果你已经有继承了,那就没办法只能选择实现接口的方式了~
继续来看看AbstractHandlerMapping这个抽象实现给我们做了哪些事情~
标签:HandlerMapping,String,Spring,getName,源码,println,super,class 来源: https://www.cnblogs.com/xfeiyun/p/15678138.html