简体   繁体   English

Spring-MVC web.xml 文件不使用 ContextLoaderListener

[英]Spring-MVC web.xml file not using ContextLoaderListener

I understand what is the purpose of the ContextLoaderListener and the DispatcherServlet.我了解 ContextLoaderListener 和 DispatcherServlet 的目的是什么。

What I do not understand is why my Sprin-MVC application will start if I DO NOT specify the ContextLoaderListener class in the web.xml file.我不明白的是,如果我没有在 web.xml 文件中指定 ContextLoaderListener 类,为什么我的 Sprin-MVC 应用程序会启动。

I would expect to see an error saying that context is missing or something similar.我希望看到一个错误,说缺少上下文或类似的东西。

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

Web.xml网页.xml

<display-name>Camel Routes</display-name>

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</context-param>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

dispatcher-servlet.xml调度程序-servlet.xml

<aop:aspectj-autoproxy/>

<context:component-scan base-package="com.crmProject"/>

<mvc:annotation-driven/>

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"/>
    <property name="suffix" value=".jsp"/>
</bean>

<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
      destroy-method="close">
    <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
    <property name="jdbcUrl" value="jdbc:mysql://mysql:3306/web_customer_tracker"/>
    <property name="user" value="root"/>
    <property name="password" value="root"/>

    <property name="initialPoolSize" value="5"/>
    <property name="minPoolSize" value="5"/>
    <property name="maxPoolSize" value="20"/>
    <property name="maxIdleTime" value="30000"/>
</bean>

<bean id="sessionFactory"
      class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="dataSource" ref="myDataSource"/>

    <property name="packagesToScan" value="com.crmProject.entity"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>

<bean id="myTransactionManager"
      class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<tx:annotation-driven transaction-manager="myTransactionManager"/>

<mvc:resources location="/resources/" mapping="/resources/**"/>

Since your context definitions seem to be very conventional and complete you do not need a ContextLoaderListener.由于您的上下文定义似乎非常传统和完整,因此您不需要 ContextLoaderListener。 Spring can handle all your configurations out of the box. Spring 可以开箱即用地处理您的所有配置。

A ContextLoaderListener comes into play if you have some weird initialization needs which cannot be handled by spring.如果您有一些 spring 无法处理的奇怪初始化需求,那么 ContextLoaderListener 就会发挥作用。 Implement your own descendant of ContextLoaderListener and configure it (either in the xml file or by annotation).实现您自己的 ContextLoaderListener 后代并对其进行配置(在 xml 文件中或通过注释)。 Your implementation is free to do what ever is needed to be done (eg fetch configurations from a non standard source in order to inject it into the spring context).您的实现可以自由地做任何需要做的事情(例如,从非标准源获取配置以将其注入 spring 上下文)。

First of all: context loaded by DispatcherServlet and context loaded by ContextLoaderListener are two different contexts.首先: DispatcherServlet加载的上下文和ContextLoaderListener加载的上下文是两个不同的上下文。

DispatcherServlet loads its context on its own. DispatcherServlet自行加载其上下文。 By default it looks for config file using template [servletName]-servlet.xml .默认情况下,它使用模板[servletName]-servlet.xml查找配置文件。 So for DispatcherServlet with name dispatcher it's gonna be dispatcher-servlet.xml .因此,对于名称为dispatcherDispatcherServlet它将是dispatcher-servlet.xml But you can specify your own file name using contextConfigLocation servlet paramter:但是您可以使用contextConfigLocation servlet 参数指定您自己的文件名:

<servlet>
   <servlet-name>dispatcher</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:custom-name-servlet.xml</param-value>
   </init-param>
   <load-on-startup>1</load-on-startup>
</servlet>

You can have multiple instances of DispatcherServlet in your application.您的应用程序中可以有多个DispatcherServlet实例。 Every instance represents separate MVC application.每个实例代表单独的 MVC 应用程序。 And every instance has its own isolated context.每个实例都有自己独立的上下文。 DispatcherServlet instances can't access contexts of each other. DispatcherServlet实例不能访问彼此的上下文。

ContextLoaderListener loads so called root context. ContextLoaderListener加载所谓的根上下文。 You can have just one root context in your application (or not to have at all).您的应用程序中可以只有一个根上下文(或者根本没有)。 And every instance of DispatcherServlet has access to this context.并且DispatcherServlet每个实例都可以访问此上下文。 So you can consider this context as a parent context while context of DispatcherServlet is a child context.因此,您可以将此上下文视为父上下文,而DispatcherServlet的上下文是子上下文。 Every time your application needs to get an instance of bean, it will look for the bean in child context first.每次您的应用程序需要获取 bean 的实例时,它都会首先在子上下文中查找 bean。 If application doesn't find bean in child context it goes to look for in root context.如果应用程序在子上下文中找不到 bean,它将在根上下文中查找。

You can find more details in Spring documentation.您可以在 Spring 文档中找到更多详细信息。 Chapter Context Hierarchy .章节上下文层次结构

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM