不使用注释

时间:2016-07-26 17:57:06

标签: spring spring-mvc

我正在尝试更详细地了解Spring MVC我目前所知道的内容。我指的是在线教程和书籍。据我了解,Spring MVC框架具有“前端控制器”和“MVC”设计模式。

前端控制器(DispatcherServlet)使用HandlerMapping将URL映射到控制器类。 我没有使用注释,因为我想了解框架在幕后的作用

在这个任务中,我创建了一个基于Spring MVC的简单Web应用程序,代码如下:

控制器代码:

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>

该应用程序按预期工作。

我无法理解的概念是在我们指定HandlerMappingViewResolver实现的spring配置xml中。

例如,我们在上面的spring xml配置中有以下bean定义:

<bean id="HandlerMapping1" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

在上面的xml配置中,org.springframework.web.servlet.handler.BeanNameUrlHandlerMappingHandlerMapping接口的实现之一。

这个bean的id是HandlerMapping1,它只是一个随机标识符(我可以很好地选择MyHandlerMapping)。以下是疑惑:

  1. 谁读取此配置文件?前端控制器是否读取此配置文件?

  2. 框架如何知道上述案例中HandlerMapping实现的ID为HandlerMapping1。通常我们会使用getBean(“beanId”),我们特别知道特定的bean id是什么。为什么spring框架会自动推断这是HandlerMapping的实现类。

  3. 理解这一点的任何输入都会有很大的帮助。

3 个答案:

答案 0 :(得分:2)

  1. 控制器不会读取xml文件,Spring会这样做。
  2. 您的spring xml配置由Spring加载,将所有内容连接在一起。正在进行自动装配,即按类型进行布线,HandlerMapping1可以为HandlerMapping接口提供布线。

    有趣的是,BeanNameUrlHandlerMapping是默认的处理程序映射类,因此当Spring无法找到声明的任何处理程序映射类时,它是由DispatcherServlet创建的。

    如果您想尝试查看某些内容,请创建一个名为HandlerMapping2的重复bean并读取错误记录。

答案 1 :(得分:1)

  1. Spring框架读取xml。
  2. 好吧,要使spring MVC正常工作,应该实例化处理程序。 Spring MVC框架需要解析映射,所以我们 有像BeanNameUrl ...,ControllerBeanNameHandlerMapping这样的处理程序, 等

    但是,您的应用程序通常不使用HandlerMapping 码。因此,您无需指定此bean是否按类型自动装配 或不。它由框架使用。所以它是自动装配的 按类型框架类。

    您可以尝试在xml中定义bean而不使用任何id,name

    之类的东西
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    

    它应该仍然有用。

    只有当您想通过id引用bean时才需要Id或name 或名称供您使用。需要此处理程序的框架类 映射不要通过id或来引用HandlerMapping类型的bean 名称。框架将扫描&#39; xml(或加载的类)和if 它在类型中找到了一个具体的类 (org.springframework.web.servlet.HandlerMapping)然后它赢了#t 抱怨。

    例如,在运行junit时,可以考虑类似的情况 测试时,引擎将扫描所有使用@Test注释的方法 它会知道&#39;这些是它需要执行的方法 试验。测试方法的名称无关紧要。

  3. 希望这可以回答查询。

答案 2 :(得分:1)

初始化

在Spring中,前端控制器是DispatcherServlet,这扩展了FrameworkServlet。默认情况下,FrameworkServlet会创建XmlWebApplicationContext并尝试读取名为<servlet-name>-servlet.xml的XML文件(这是在使用web.xml时!)。 (所有这些都可以通过为配置的init-param设置适当的DispatcherServlet来覆盖。

加载后DispatcherServlet将最终调用initStrategies方法。此方法将为DispatcherServlet配置委派策略。它会首先尝试按类型检测大多数策略(例如HandlerMapingHandlerAdapterViewResolver等),有些则按名称(localeResolverthemeResolver检测, messageSource等)。如果找不到,则将安装给定接口的默认策略。这些默认值在Spring中的DispatcherServlet.properties中定义。

重要提示:只要您自己定义策略,该策略的默认设置就不再适用了!例如,如果您的配置中有BeanNameUrlHandlerMapping,则HandlerMapping的默认配置将不再加载,因为您提供了显式配置。

请求处理

启动后,DispatcherServlet已准备好处理请求。

DispatcherServlet Flow 图片来自Spring Framework reference guide

处理程序选择和执行

DispatcherServlet处理请求时,会检查所有已配置的HandlerMapping以查看是否能够提供处理程序(Controller或{{1}对于给定的请求,它只是可以处理的一种处理程序类型。一旦找到处理程序,它就会为检测处理程序查找HandlerAdapter。如果找到了,则将找到的处理程序与当前@ControllerHttpServletRequest一起传递给HttpServletResponse HandlerAdapter方法。

查看分辨率

现在,如果handle方法返回ModelAndView,如果HandlerAdapter.handle方法返回名称,则View将被解析,这将是将a传递给ViewResolver以解析为View

ModelAndView.getViewName()是解析程序或从View方法返回时,将调用ModeAndView.getView()方法让所选的render呈现自己。使用View类中的(可选)模型。

异常处理

在处理请求期间发生异常时,首先将此异常传递给配置的HandlerExceptionResolver。如果其中一个人可以处理它,则会调用所选的ModelAndView s HandlerExceptionResolver方法。与resolveException方法一样,此方法可以返回HandlerAdapter.handle,当发生这种情况时,其处理方式与正常请求相同(请参阅查看解析)。

注意: ModelAndView的{​​{3}}中也记录了这一点。您可以在其中找到所有默认策略和众所周知的名称,以及请求处理流程的说明。