我正在尝试更详细地了解我目前所知道的 Spring MVC。我指的是在线教程和书籍。据我了解,Spring MVC 框架具有“前端 Controller ”和“MVC”设计模式。
前端 Controller (DispatcherServlet) 使用 HandlerMapping
将 URL 映射到 Controller 类。 我没有使用注释,因为我想了解框架在幕后做了什么。
在这个任务中,我创建了一个基于 Spring MVC 的简单 Web 应用程序,代码如下:
Controller 代码:
public class SimpleSpringController extends AbstractController {
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse res) throws Exception {
ModelAndView mw = new ModelAndView("welcome","welcomeMessage", "welcome user!");
return mw;
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<display-name>FirstSpringMVCProject</display-name>
<servlet>
<servlet-name>spring-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Spring xml配置
<beans>
<bean id="HandlerMapping1" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean name="/welcome" class="com.example.controller.SimpleSpringController"/>
<bean id="viewResolver1" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix"> <value>/WEB-INF/</value> </property>
<property name="suffix"> <value>.jsp</value> </property>
</bean>
</beans>
应用程序按预期工作。
我无法理解的概念是在 spring 配置 xml 中,我们在其中指定了 HandlerMapping
和 ViewResolver
实现。
比如我们在上面的spring xml配置中有如下bean定义:
<bean id="HandlerMapping1" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
在上面的xml配置中,org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
是HandlerMapping
接口(interface)的实现之一。
这个 bean id 是 HandlerMapping1
,它只是一个随机标识符(我可以很好地选择 MyHandlerMapping
)。以下是疑点:
谁读取这个配置文件?前端 Controller 是否读取这个配置文件?
框架如何知道上面例子中
HandlerMapping
实现的id是HandlerMapping1
。通常我们做 getBean("beanId"),我们特别知道特定的 bean id 是什么。 spring framework怎么自动推断这是HandlerMapping
的实现类。
理解这一点的任何输入都会有很大帮助。
最佳答案
初始化
在 Spring 中,前端 Controller 是 DispatcherServlet
, 这扩展了 FrameworkServlet
. FrameworkServlet
默认创建一个 XmlWebApplicationContext
并尝试读取名为 <servlet-name>-servlet.xml
的 XML 文件(这是在使用 web.xml
时!)。 (所有这些都可以通过为配置的 init-param
设置适当的 DispatcherServlet
来覆盖)。
DispatcherServlet
加载后最终会调用 initStrategies
方法。此方法将为 DispatcherServlet
配置委派策略.它将首先尝试按类型检测大多数策略(如 HandlerMaping
、HandlerAdapter
、ViewResolver
等)和一些按名称(localeResolver
、themeResolver
、messageSource
等)的策略。如果找不到,将安装给定接口(interface)的默认策略。这些默认值在 DispatcherServlet.properties
中定义 Spring 里面。
重要提示:一旦您自己定义策略,该策略的默认值就不再适用!。例如,如果你有一个 BeanNameUrlHandlerMapping
在您的配置中,HandlerMapping
的默认配置不再加载,因为您提供了显式配置。
请求处理
启动后DispatcherServlet
已准备好处理请求。
图片来自Spring Framework reference guide
处理程序选择和执行
当请求被 DispatcherServlet
处理时会发生什么它将检查所有已配置的 HandlerMapping
查看是否能够为给定请求提供处理程序(Controller
或 @Controller
只是可以处理的处理程序类型之一)。一旦找到处理程序,它将查找 HandlerAdapter
对于检测处理程序。如果还找到了找到的处理程序以及当前的 HttpServletRequest
和 HttpServletResponse
传递给 HandlerAdapter
s handle
方法。
查看分辨率
现在如果一个 ModelAndView
正在从 HandlerAdapter.handle
返回方法一View
如果 ModelAndView.getViewName()
将得到解决方法返回一个名称,这将通过 an 传递给 ViewResolver
被解析为 View
.
当 View
正在解析器或从 ModeAndView.getView()
返回方法,render
方法将被调用让选择的View
呈现自己。使用来自 ModelAndView
的(可选)模型类(class)。
异常处理
当处理请求期间发生异常时,此异常首先被传递给配置的 HandlerExceptionResolver
秒。如果其中之一可以处理它,则选定 HandlerExceptionResolver
s resolveException
正在调用方法。这个方法,就像HandlerAdapter.handle
方法可以返回 ModelAndView
,当发生这种情况时,它的处理方式与正常请求相同(请参阅查看分辨率)。
注意:这也在一定程度上记录在 javadoc 中的 DispatcherServlet
.您可以在其中找到所有默认策略和众所周知的名称,以及请求处理流程的说明。
关于spring - 在不使用注释的情况下需要对 Spring MVC 进行说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38596814/