现在JavaConfig配置方式在逐步取代xml配置方式。而WebApplicationInitializer可以看做是Web.xml的替代,它是一个接口。通过实现WebApplicationInitializer,在其中可以添加servlet,listener等,在加载Web项目的时候会加载这个接口实现类,从而起到web.xml相同的作用。下面就看一下这个接口的详细内容。

首先打开这个接口,如下:

public interface WebApplicationInitializer {void onStartup(ServletContext var1) throws ServletException;
}

只有一个方法,看不出什么头绪。但是,在这个包下有另外一个类,SpringServletContainerInitializer。它的实现如下:

package org.springframework.web;import java.lang.reflect.Modifier;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;@HandlesTypes({WebApplicationInitializer.class})
public class SpringServletContainerInitializer implements ServletContainerInitializer {public SpringServletContainerInitializer() {}public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {List<WebApplicationInitializer> initializers = new LinkedList();Iterator var4;if(webAppInitializerClasses != null) {var4 = webAppInitializerClasses.iterator();while(var4.hasNext()) {Class<?> waiClass = (Class)var4.next();if(!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) {try {initializers.add((WebApplicationInitializer)waiClass.newInstance());} catch (Throwable var7) {throw new ServletException("Failed to instantiate WebApplicationInitializer class", var7);}}}}if(initializers.isEmpty()) {servletContext.log("No Spring WebApplicationInitializer types detected on classpath");} else {servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");AnnotationAwareOrderComparator.sort(initializers);var4 = initializers.iterator();while(var4.hasNext()) {WebApplicationInitializer initializer = (WebApplicationInitializer)var4.next();initializer.onStartup(servletContext);}}}
}

这个类就比较有意思了,先不管其他的,读一下这段代码,可以得到这样的意思。

先判断webAppInitializerClasses这个Set是否为空。如果不为空的话,找到这个set中不是接口,不是抽象类,并且是

WebApplicationInitializer接口实现类的类,将它们保存到list中。当这个list为空的时候,抛出异常。不为空的话就按照一定的顺序排序,并将它们按照一定的顺序实例化。调用其onStartup方法执行。到这里,就可以解释WebApplicationInitializer实现类的工作过程了。但是,在web项目运行的时候,SpringServletContainerInitializer这个类又是怎样被调用的呢。

它只有一个接口,ServletContainerInitializer,通过它就可以解释SpringServletContainerInitializer是如何被调用的。它的内容如下:

package javax.servlet;import java.util.Set;public interface ServletContainerInitializer {void onStartup(Set<Class<?>> var1, ServletContext var2) throws ServletException;
}

首先,这个接口是javax.servlet下的。官方的解释是这样的:为了支持可以不使用web.xml。提供了ServletContainerInitializer,它可以通过SPI机制,当启动web容器的时候,会自动到添加的相应jar包下找到META-INF/services下以ServletContainerInitializer的全路径名称命名的文件,它的内容为ServletContainerInitializer实现类的全路径,将它们实例化。既然这样的话,那么SpringServletContainerInitializer作为ServletContainerInitializer的实现类,它的jar包下也应该有相应的文件。打开查看如下:

哈,现在就可以解释清楚了。首先,SpringServletContainerInitializer作为ServletContainerInitializer的实现类,通过SPI机制,在web容器加载的时候会自动的被调用。(这个类上还有一个注解@HandlesTypes,它的作用是将感兴趣的一些类注入到ServletContainerInitializerde), 而这个类的方法又会扫描找到WebApplicationInitializer的实现类,调用它的onStartup方法,从而起到启动web.xml相同的作用。

然后,我们自己通过一个实例来实现相同的功能,通过一样的方式来访问一个servlet。

1、定义接口WebParameter,它就相当于WebApplicationInitializer。内容如下:

public interface WebParameter {void loadOnstarp(ServletContext servletContext);
}

可以在这里面添加servlet,listener等。

2、定义Servlet。

public class MyServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write("TestSetvlet");}
}

3、定义MyWebParameter作为WebParameter的实现类,将Servlet添加到上下文,并设置好映射。

public class MyWebParameter implements WebParameter {public void loadOnstarp(ServletContext servletContext) {ServletRegistration.Dynamic testSetvelt=servletContext.addServlet("test","com.test.servlet.MyServlet");testSetvelt.setLoadOnStartup(1);testSetvelt.addMapping("/test");}
}

当然,也可以把第2步和第3步合在一起:

public class MyServlet extends HttpServlet implements WebParameter {@Overridepublic void loadOnstarp(ServletContext servletContext) {ServletRegistration.Dynamic testSetvelt=servletContext.addServlet("test","com.test.servlet.MyServlet");testSetvelt.setLoadOnStartup(1);testSetvelt.addMapping("/test");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write("TestSetvlet");}
}

而且以后可以将Spring的applicationContext.xml与web.xml融合在一个类中。即注解为@Configuration,并实现WebApplicationInitializer。

4、定义好WebConfig作为ServletContainerInitializer的实现类,它的作用是扫描找到WebParameter的实现类,并调用其方法。

@HandlesTypes({WebParameter.class})
public class WebConfig implements ServletContainerInitializer {public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {Iterator var4;if (set!=null){var4=set.iterator();while(var4.hasNext()){Class<?> clazz= (Class<?>) var4.next();if (!clazz.isInterface()&& !Modifier.isAbstract(clazz.getModifiers())&&WebParameter.class.isAssignableFrom(clazz)){try {((WebParameter) clazz.newInstance()).loadOnstarp(servletContext);}catch (Exception e){e.printStackTrace();}}}}}
}

5、根据SPI机制,定义一个META-INF/services文件夹,并在其下定义相关文件名称,并将WebConfig的类全名称填入其中。

6、最终结果:

本文转自:https://blog.csdn.net/zq17865815296/article/details/79464403

转载于:https://www.cnblogs.com/nizuimeiabc1/p/11031150.html

Spring中WebApplicationInitializer的理解相关推荐

  1. 【Java基础】Spring 中 Bean 的理解与使用

    大白话讲解: 从广义上 Spring 注解可以分为两类: 一类注解是用于注册 Bean 假如 IoC 容器是一间空屋子,首先这间空屋子啥都没有,我们要吃大餐,我们就要从外部搬运食材和餐具进来.这里把某 ...

  2. Spring中Bean的理解以及@Bean的作用

    Bean在Spring和SpringMVC中无所不在,将这个概念内化很重要,下面分享一下我的想法: 一.Bean是啥 1.Java面向对象,对象有方法和属性,那么就需要对象实例来调用方法和属性(即实例 ...

  3. Spring中的IOC理解

    相关概念 Spring 通过一个配置文件描述 Bean 及 Bean 之间的依赖关系,利用 Java 语言的反射功能实例化 Bean 并建立 Bean 之间的依赖关系. Spring 的 IoC 容器 ...

  4. 对spring 中IOC 的理解

    IOC 即"控制反转" 不是技术, 是一种思想.使用ioc 意味着将你设计好的对象交给容器来管理,而不是传统的在你的对象内部直接进行管理.而spring通过我们在xml 中的配置和 ...

  5. Spring中IOC的理解(通俗易懂版)

    文章目录 1.IOC提出背景 2:IOC的核心概念 3:IOC的实现方式 4:IOC的入门案例 (1):思路分析 (2):代码解析 5:DI入门案例 (1):思路分析 (2):代码解析 6:DI依赖注 ...

  6. Spring中对于WebApplicationInitializer的理解

    文章目录 1.前言 2.WebApplicationInitializer的定义 3.实现原理 4.利用SPI我们能做什么? 4.1.定义一个`MyWebAppInitializer` 4.2.定义一 ...

  7. spring(7)---深入理解Spring核心技术——Spring中的各模块详解

    深入理解Spring核心技术--Spring中的各模块详解 Spring框架的两个基本概念IOC容器和AOP,相信大家现在对Spring中的这两个部分的基本概念有了一定的认识,好了,那么今天我们就来正 ...

  8. SpringCloud学习笔记010---杂七杂八004:Spring中Bean及@Bean的理解

    Bean在Spring和SpringMVC中无所不在,将这个概念内化很重要,下面分享一下我的想法: 一.Bean是啥 1.Java面向对象,对象有方法和属性,那么就需要对象实例来调用方法和属性(即实例 ...

  9. python ioc框架_轻松理解 Spring 中的 IOC

    Spring 简介 Spring 是一个开源的轻量级的企业级框架,其核心是反转控制 (IoC) 和面向切面 (AOP) 的容器框架.我们可以把 Spring 看成是对象的容器,容器中可以包含很多对象, ...

最新文章

  1. java 连接sqlitle_ASP连接SQL2005数据库连接代码
  2. android handler2--消息队列源码解析
  3. LDA主题模型(算法详解)
  4. 升级nodeJS中的npm版本
  5. 34_注解的定义与反射调用
  6. linux下运行jar
  7. 李宏毅:1天搞懂深度学习,我总结了 300 页 PPT(附思维导图PPT)
  8. windows 无法加载DLL “***.dll”:找不到指定的模块
  9. 把小写金额转成大写金额 (Java经典编程案例)
  10. 数据仓库模型设计及实施方法
  11. 解决“试图加载格式不正确的程序”问题
  12. 通过扫描二维码进入下载APP的流程
  13. 拾方易公众号运营成本低么?
  14. ASP一叶知秋 SaaS将会成为08重点
  15. 主数据与数据中台有什么区别?
  16. 洛谷P5594-【XR-4】模拟赛
  17. 如何在 Ubuntu 20.04 / KylinOS-V10-SP1 上安装 Sublime Text 4
  18. php不能上传doc文件,PHPCMS不能上传WORD、EXCEL等文件的问题
  19. 百度与360的搜索战
  20. 机器学习——NB算法(包括符号型与数值型两种)

热门文章

  1. (转)Java中的守护线程
  2. saltstack二
  3. Bootstrap页面布局14 - BS按钮群组
  4. MySql简介及概念
  5. DHCP|什么是DHCP|DHCP介绍
  6. ELK 6.2.4搭建
  7. Java语言与sikuli配合
  8. 浅析微信支付:申请退款、退款回调接口、查询退款
  9. Spring Boot 静态资源访问原理解析
  10. 【pl/sql番外篇】 存储过程 游标