接口就是: org.springframework.web.servlet.HandlerAdapter
策略就是:org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter方法,根据策略获取不同的HandlerAdapter实现
配置文件就是: DispatcherServlet.properties (默认)
- spring mvc 转发入口
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { ModelAndView mv = null; Exception dispatchException = null; try { processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); // Determine handler for the current request. mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request. // 根据策略获取不同的实现 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
- org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter 方法获取策略实现
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { if (this.handlerAdapters != null) { // 循环匹配使用哪个策略, this.handlerAdapters 对象是在org.springframework.web.servlet.DispatcherServlet#initHandlerAdapters 方法中进行初始化的 for (HandlerAdapter adapter : this.handlerAdapters) { if (adapter.supports(handler)) { return adapter; } } } throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); }
org.springframework.web.servlet.DispatcherServlet#initHandlerAdapters 方法初始化handlerAdapters 对象时会调用
org.springframework.web.servlet.DispatcherServlet#getDefaultStrategies 加载默认策略
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) { String key = strategyInterface.getName(); // defaultStrategies 中就是策略的默认配置 String value = defaultStrategies.getProperty(key); if (value != null) { String[] classNames = StringUtils.commaDelimitedListToStringArray(value); List<T> strategies = new ArrayList<>(classNames.length); for (String className : classNames) { try { Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader()); Object strategy = createDefaultStrategy(context, clazz); strategies.add((T) strategy); } catch (ClassNotFoundException ex) { throw new BeanInitializationException( "Could not find DispatcherServlet's default strategy class [" + className + "] for interface [" + key + "]", ex); } catch (LinkageError err) { throw new BeanInitializationException( "Unresolvable class definition for DispatcherServlet's default strategy class [" + className + "] for interface [" + key + "]", err); } } return strategies; }
- defaultStrategies 是怎么从配置文件中加载资源的
DispatcherServlet 类的静态块加载配置, 配置文件的默认路径就是DispatcherServlet.properties
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties"; private static final Properties defaultStrategies; static { // Load default strategy implementations from properties file. // This is currently strictly internal and not meant to be customized // by application developers. try { ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class); defaultStrategies = PropertiesLoaderUtils.loadProperties(resource); } catch (IOException ex) { throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage()); } }
看一下DispatcherServlet.properties 中的配置
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping, org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping, org.springframework.web.servlet.function.support.RouterFunctionMapping org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter, org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter, org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter, org.springframework.web.servlet.function.support.HandlerFunctionAdapter org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver, org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver, org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
最后
以上就是典雅刺猬最近收集整理的关于spring mvc 中的SPI应用的全部内容,更多相关spring内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复