Spring中WebApplicationInitializer的理解
现在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 {
-
@Override
-
protected 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");
-
}
-
}
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的类全名称填入其中。
至此,相关内容就完成了,因为我用的maven,通过install将其作为jar包上传到本地仓库。从另外一个web项目调用这个包进行访问。
6、最终结果:
相关代码请转至我的github点击打开链接
ps:其中涉及到了SPI相关的内容,如果不懂请自行百度。如果认识有误,请大佬指出,谢谢。
Spring中WebApplicationInitializer的理解的更多相关文章
- Spring中IOC的理解
Spring中IOC的理解 1.什么是IOC? (1)控制反转.把对象创建和对象间的调用过程交给Spring进行管理. (2)使用IOC的目的:为了耦合度降低. 2.IOC底层原理? (1)xml解析 ...
- 关于Spring中AOP的理解
AOP简介[理解][重点] 1.AOP(Aspect Oriented Programing)面向切面/方面编程 2.AOP隶属软件工程的范畴,指导开发人员如何制作开发软件,进行结构设计 3.AOP联 ...
- 浅析对spring中IOC的理解
学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...
- Spring中AOP的理解
1.AOP的概念 AOP(AspectOriented Programming,面向切面编程)指的是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下个程序动态统一添加功能的一种技术.AOP ...
- Spring中Configuration的理解
基本用途从Spring3.0,@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigAp ...
- spring中的ResponseEntity理解
参考: https://blog.csdn.net/weixin_37869477/article/details/82762976 https://blog.csdn.net/sswqzx/arti ...
- 深入理解spring中的各种注解
Spring中的注解大概可以分为两大类: 1)spring的bean容器相关的注解,或者说bean工厂相关的注解: 2)springmvc相关的注解. spring的bean容器相关的注解,先后有:@ ...
- Spring学习(二)——Spring中的AOP的初步理解[转]
[前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...
- 深入理解spring中的各种注解(转)
Spring中的注解大概可以分为两大类: 1)spring的bean容器相关的注解,或者说bean工厂相关的注解: 2)springmvc相关的注解. spring的bean容器相关的注解,先后有:@ ...
随机推荐
- QQ在线交谈代码
非常多商业站点的右边都会有一个固定或者浮动的层显示QQ在线在线交谈或者咨询的button.当浏览者点击了就会弹出相应的对话框. 这里的QQ交谈有两种: 一种是企业QQ,那要生成以上的功能就非常easy ...
- C++组合数(combination)的实现
实现: (nm) 既需要计算组合的总数 (32)=3: 也需要分别获得每一种组合的情形,用于穷举搜索: 1, 2; 1, 3; 2, 3 1. 递归实现 // picked + toPick == m ...
- (转)Windows Server 2012 R2虚拟机自激活(AVMA)技术
转自: 老丁的技术博客 相信Hyper-v管理员都有这样的经历,安装多台虚拟机后,都要一台一台手工激活,如果虚拟机足够多的话,这是一项很繁琐的工作,但从Windows Server 2012 R2开始 ...
- Xvisor ARM32 启动分析
Linux内核历史悠久,特性丰富,但是代码量庞大,各个子系统交叉繁琐.对于想要将操作系统内核各个特性研究一遍的人,有时候也只好"望Linux兴叹".Xvisor是一个较新的Type ...
- swift项目第一天:环境部署
一:项目部署 项目部署 一.开源中国(OSChina) 网站地址:https://git.oschina.net/ 开源中国社区成立于2008年8月,其目的是为中国的IT技术人员提供一个全面的.快捷更 ...
- Dll的链接使用细节
关于Dll Dll.Exe 都是PE格式的二进制文件. Dll相当于Linux操作系统下的so文件 1 基地址(Base Address)和相对地址(RelativeVirtual Address) ...
- MVC5管道处理模型
原文:MVC5管道处理模型 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/m0_37591671/article/details/82970442 ...
- 【计算机】基本概念的理解 —— 沙盒(sandbox)、交互式计算/编程/应用
web scraper:网络铲: scraper:n. 刮刀:铲土机:守财奴: 1. 交互式计算/编程/应用(interactive computing/application/programming ...
- 向 Windows 高级用户进阶,这 10 款效率工具帮你开路 | 新手问号
原文地址:https://sspai.com/post/41411 编注:「新手问号」是少数派的一个全新栏目.它面向完全「零基础」的新手用户,通过最简单易懂的方式,帮助你快速掌握关于系统和软硬件的入门 ...
- LOG4J中日志级别的使用
<logger name="demo-log" additivity="false"> <level value="${log.le ...