zoukankan      html  css  js  c++  java
  • servlet 3 通过编程的方式来配置ServletContext

    你是否再为配置文件web.xml容易出错而烦恼?是否为web.xml文件存放位置而不知所措?是否为web.xml为什么要这样配?怎么才能更好的配置web.xml而烦恼?那么一种新的方式出现了:

    spring提供了支持servlet 3+以上的编程方式,它可以替换或者和web.xml共存的方式工作。其相关类如下:

    WebApplicationInitializer

      传统上,我们基于web.xml这种方式来配置web应用,而WebApplicationInitializer的实现支持在servlet 3.0以上的环境里通过编程的方式来配置ServletContext,这种方式既可以替换web.xml这种方式,也可以和web.xml这种方式共存。

      这种SPI的实现通常由SpringServletContainerInitializer来自动发现,SpringServletContainerInitializer可以被servlet 3.0以上的容器自动启动。详细请参考下面的章节。示例如下:

       传统基于xml的方式

        绝大多数spring开发者构建web应用时需要注册spring DispatcherServlet到WEB/web.xml如下方式:

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>
          org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
     
      <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>

       基于编程方式的WebApplicationInitializer

    下面基于WebApplicationInitializer样式的代码等同于DispatcherServlet的注册逻辑:

    public class MyWebAppInitializer implements WebApplicationInitializer {
     
         @Override
         public void onStartup(ServletContext container) {
           XmlWebApplicationContext appContext = new XmlWebApplicationContext();
           appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
     
           ServletRegistration.Dynamic dispatcher =
             container.addServlet("dispatcher", new DispatcherServlet(appContext));
           dispatcher.setLoadOnStartup(1);
           dispatcher.addMapping("/");
         }
     
      }

    上面的实现,还可以通过扩展org.springframework.web.servlet.support.AbstractDispatcherServletInitializer实现。

      如上所示,归功于servlet3.0的ServletContext#addServlet方法,我们注册一个DispatcherServlet的实例,这意味着DispatcherServlet可以如其他Object一样,接受在应用上下文中通过构造器进行注入。

      这种方式不但简单还很明了。不需要关注init-param的处理等等,仅有通常的javaBean样式的属性和构造参数。可以在DispatcherServlet注入之前,尽可能的自由的创建spring context、使用spring context。

      绝大部分spring web组件已经更新来支持这种注册方式,你会发现DispatcherServlet、FrameworkServlet、ContextLoaderListener和DelegatingFilterProxy现在都支持构造参数。

      尽管个别组件(非spring的,其他第三方的)没有更新到支持WebApplicationInitializer的使用,它们仍然可以使用。servlet 3.0的ServletContext api支持编码式设置init-params,context-param等的属性。

      基于编码式的配置

      上例中,WEB/web.xml可以通过WebApplicationInitializer样式的代码完全替换掉,但真正的dispatcher-config.xml spring配置文件仍然是基于xml方式的。WebApplicationInitializer也是一个很棒的方式来进行spring的基于编程方式的配置类,详情参考org.springframework.context.annotation.Configuration。

         下面的例子中,将使用spring的

    org.springframework.web.context.support.AnnotationConfigWebApplicationContext
    类来替代XmlWebApplicationContext,用户自定义的@Configuration配置类AppConfig和DispatcherConfig来替换spring的xml文件来重构上面的例子。这个示例也有一些超出部分,用来展示root application context的的通用配置和ContextLoaderListener的注册:

    public class MyWebAppInitializer implements WebApplicationInitializer {
     
         @Override
         public void onStartup(ServletContext container) {
           // Create the 'root' Spring application context
           AnnotationConfigWebApplicationContext rootContext =
             new AnnotationConfigWebApplicationContext();
           rootContext.register(AppConfig.class);
     
           // Manage the lifecycle of the root application context
           container.addListener(new ContextLoaderListener(rootContext));
     
           // Create the dispatcher servlet's Spring application context
           AnnotationConfigWebApplicationContext dispatcherContext =
             new AnnotationConfigWebApplicationContext();
           dispatcherContext.register(DispatcherConfig.class);
     
           // Register and map the dispatcher servlet
           ServletRegistration.Dynamic dispatcher =
             container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
           dispatcher.setLoadOnStartup(1);
           dispatcher.addMapping("/");
         }
     
      }

  • 相关阅读:
    python 3.x 不再提供raw_print()
    php中fileatim,filectime和filemtime函数的区别
    如何将文本以BLOB类型存入数据库并取出
    tomcat启动不了——Error initializing endpoint——java.net.BindException: Address already in use: JVM_Bind
    hdu 2188(巴什博弈入门 )
    hdu 2187(贪心)
    Sentinel数据处理工具包SNAP Python开发环境搭建
    conda 安装包命令
    使用SSH连接WSL
    win10 安装WSL 出现 WslRegisterDistribution failed with error: 0x8000000d
  • 原文地址:https://www.cnblogs.com/zhaoyanhaoBlog/p/11936116.html
Copyright © 2011-2022 走看看