`

spring中的WebApplicationInitializer

 
阅读更多

 

XML-based Approach

要配置核心分发控制器Servlet,即DispatcherServlet,传统做法是直接使用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>
 

 

Code-based Approach

在Spring3.1开始可以使用Servlet3.0技术,实现代码编写注册核心控制器。

 

@Order(100)//指定加载顺序,不指定默认为最小,即最先执行,或者实现Ordered 接口也行
public class MyWebAppInitializer implements WebApplicationInitializer {

   @Override
   public void onStartup(ServletContext container) {
//这两行是为了加载springmvc的配置
     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.
 

 

一旦编写以上类,且将其放置在类路径上,则服务器启动时日志会打印如下日志:

2017-03-01 23:33:05.529:INFO:/:main: 2 Spring WebApplicationInitializers detected on classpath

对于以上内容,dispatch-config.xml还是依赖xml配置,我们还是可以使用AnnotationConfigWebApplicationContext,完全基于@Configuration使用。

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("/");
   }
}

 

注意:

web.xml与以上方式并不冲突,可以相互并存,甚至可以做到后者硬编码修改web.xml配置,例如使用ServletContext.getServletRegistration(String)。

实现原理分析

在Spring-web项目中有类SpringServletContainerInitializer,它实现了Servlet3.0的ServletContainerInitializer接口,且优先级会高于xml中配置的listener。在SpringServletContainerInitializer中有注解@HandlesTypes(WebApplicationInitializer.class),具体如下:

  1. 因为这个类声明了HandlesTypes,并指定了类型为WebApplicationInitializer.class,在Servlet3.0+中web容器启动时,会扫描类路径下所有的WebApplicationInitializer接口实现类,并提供一个set集合给onStartup方法执行。
  2. onStartup方法执行时,会遍历该set,并使用newInstance()方式进行实例化,实例化后依据@Order注解进行排序,最后在依次调用onStartup(ServletContext)方法,完成初始化。
    public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
        throws ServletException {
    
      List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>();
    
      if (webAppInitializerClasses != null) {
        for (Class<?> waiClass : webAppInitializerClasses) {
          // Be defensive: Some servlet containers provide us with invalid classes,
          // no matter what @HandlesTypes says...
          if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
              WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
            try {
              initializers.add((WebApplicationInitializer) waiClass.newInstance());
            }
            catch (Throwable ex) {
              throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
            }
          }
        }
      }
    
      if (initializers.isEmpty()) {
        servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
        return;
      }
    
      servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
      AnnotationAwareOrderComparator.sort(initializers);
      for (WebApplicationInitializer initializer : initializers) {
        initializer.onStartup(servletContext);
      }
    }
     

总结:

  1. 引入spring-web包后,web.xml配置metadata-complete=false,其实默认不配置就是false,并确保运行环境支持servlet3.0+,就可以不需要再用以前的方式,在web.xml中配置listener或servlet了。
  2. WebApplicationInitializer类可以说是SpringWeb的核心初始化器,可用来初始化注册监听器,包括以往的ContextLoadListener。
分享到:
评论

相关推荐

    eclips项目的正常的settings文件

    1. **检查类路径**:确保包含所有必要的Spring库,特别是`spring-web`和`spring-webmvc`模块,因为`WebApplicationInitializer`位于`spring-web`中。 2. **检查初始化类**:确认至少有一个类实现了`...

    spring-boot-2.7.0.zip源码

    4. **Web应用启动**:Spring Boot的`WebApplicationInitializer`和`SpringBootServletInitializer`类是用于启动Web应用的关键。它们实现了Servlet 3.0的接口,使得应用可以不依赖于web.xml启动。 5. **Actuator模块...

    Spring 5.0 web 官方文档 转PDF

    例如,下面的MyWebApplicationInitializer类实现了WebApplicationInitializer接口,它在onStartup方法中负责加载Spring Web应用配置,并创建并注册DispatcherServlet。 public class MyWebApplicationInitializer ...

    Spring 和 Spring Boot 之间到底有啥区别?.docx

    在传统的Spring项目中,需要手动配置WebApplicationInitializer,而Spring Boot则简单得多,只需一个`spring-boot-starter-web`依赖即可自动配置Web环境。测试库的依赖管理也是类似,Spring Boot的`spring-boot-...

    spring-thrift-integration:示例如何将Thrift集成到Spring应用程序中

    这是一个示例,展示了如何在不使用Spring Boot的情况下将集成到Spring应用程序中。 相反,它依赖于Spring的WebApplicationInitializer类,因此不需要web.xml。 如何建造 让Maven编译代码: mvn compile 如果出现...

    spring4.1源码

    Spring的Web MVC框架在4.1版本中进行了优化,支持RESTful风格的控制器,增强了模型视图解析器(ViewResolver)的灵活性,同时引入了WebApplicationInitializer接口,使得无需web.xml就能初始化Spring MVC应用。...

    Spring Boot2 教程1

    Spring Boot项目不再需要`web.xml`,而是通过实现`WebApplicationInitializer`接口来自定义项目启动时的初始化操作,如加载Spring MVC容器。 在实际开发中,有时为了简化配置,所有配置可能会合并到Spring MVC的...

    spring-boot 过滤器 filter

    1. 实现`javax.servlet.Filter`接口:创建一个类,实现`doFilter()`方法,然后在`WebApplicationInitializer`或`WebMvcConfigurer`接口的实现类中注册该过滤器。 ```java public class MyFilter implements Filter ...

    使用注解将 Vaadin 6.7.3 和 Spring 3.0.5 整合 (一)

    在本篇博文中,我们将探讨如何整合Vaadin 6.7.3,一个基于Java的Web应用程序框架,与Spring 3.0.5,一个流行的轻量级Java应用框架,来构建高效、可维护的MVC架构的应用程序。这篇教程的重点在于使用注解的方式进行...

    Spring MVC总结(一)

    * 如果使用Spring 3.1,可以通过实现WebApplicationInitializer接口(listing 4) 在项目中,每一个模块一个jar包,可以在该jar包中使用web-fragment.xml文件,该文件放置在META-INF目录中,且在一个jar包中。该...

    通过Java配置实现的Spring Boot中大量的自动化配置.docx

    在本教程中,我们将探讨如何使用Java配置在Spring Boot中实现自动配置,这将帮助我们构建更加简洁且高效的项目结构。首先,我们需要创建一个基础的Maven工程,并配置相关的依赖。 1. 创建工程: 创建一个普通的...

    Spring Boot2 教程.pdf

    可以创建一个实现了`WebApplicationInitializer`接口的类,如`WebInit`,在`onStartup`方法中初始化SpringMVC容器和其他必要组件。 值得注意的是,如果要在SpringMVC中加载Spring容器,需要在SpringMVC配置的包扫描...

    Spring boot +jdbctemplate

    - **WebApplicationInitializer**:Spring Boot自动配置Servlet、Filter和Listener,无需传统web.xml配置。 - **DispatcherServlet**:Spring Boot会默认创建一个DispatcherServlet,处理所有HTTP请求。 - **...

    Spring 4 + REST Web Service + JSON Example with Tomcat

    服务器启动时,由WebApplicationInitializer初始化Spring配置。 最终访问地址 -&gt; http:// localhost:8080 / 工程名 / data / person?id = 15 输出将显示如下 ↓ JSON { “id” :15 ,“location” :“Varanasi...

    Spring新特性之Java Config在Web开发中的应用.zip

    8. **Web应用中的Java Config**:在Web开发中,Spring提供了`WebMvcConfigurer`和`WebApplicationInitializer`接口,用于配置Spring MVC。通过实现这些接口,我们可以定制DispatcherServlet的设置,包括拦截器、视图...

    Spring 和 Spring Boot的区别

    - **Spring MVC**:在 Spring 中,配置 MVC 需要定义调度器 Servlet、映射等,可能涉及 web.xml 或使用 WebApplicationInitializer。而在 Spring Boot 中,通过 @SpringBootApplication 注解即可自动配置 MVC。 ...

    Spring+SpringMVC配置加载顺序1

    Spring 提供了名为 SpringServletContainerInitializer (SSCI) 的实现,它进一步查找并使用实现了 WebApplicationInitializer 接口的类来配置 Servlet 容器。 Spring 3.2 引入了对注解配置的支持,提供了一个抽象类...

    springboot集成axis2-1.7.9实例

    在本文中,我们将深入探讨如何将Apache Axis2与Spring Boot集成,以构建一个高效、可扩展的Web服务应用。Apache Axis2是Java平台上的一个Web服务框架,它提供了高性能、灵活的服务开发和部署机制。而Spring Boot是...

    Spring Boot 视频

    4. **WebApplicationInitializer**:理解 Spring Boot 如何实现无 XML 的 Web 应用初始化。 ### 三、Spring Boot 工具使用 1. **Spring Initializr**:在线生成 Spring Boot 项目结构,快速搭建项目基础。 2. **...

    Spring-MVC-model

    在Spring 3.2.6版本中,该框架已经相当成熟和完善,为开发者提供了丰富的功能和高度的灵活性。与Hibernate 4集成,可以方便地处理数据库操作,实现数据持久化。 1. **Spring MVC 框架核心组件** - **...

Global site tag (gtag.js) - Google Analytics