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容器相关的注解,先后有:@ ...
随机推荐
- 几个移动web app开发框架
几个移动web app开发框架 一.总结 1.有amaze ui,有app.js(登录注册界面用到的) 二.几个移动web app开发框架 jQuery Mobile jQuery Mobile框架 ...
- SQl 事务增加数据
连SQl简单地事务处理多表的情况 begin transaction declare @error int declare @QID int set @error = 0 insert into HW ...
- 使用javascript实现图片上下切换效果并且实现顺序循环播放
<!doctype html><html lang="en"><head> <meta charset="UTF-8" ...
- js进阶 12-16 jquery如何实现通过点击按钮和按下组合键两种方式提交留言
js进阶 12-16 jquery如何实现通过点击按钮和按下组合键两种方式提交留言 一.总结 一句话总结:实现按下组合键提交留言是通过给input加keydown事件,判断按键的键码来实现的. 1.如 ...
- 系统学习java高并发系列一
转载请注明原创出处,谢谢! JAVA服务端或者后端需要大量的高并发计算,所以高并发在JAVA服务端或者后端编程中显的格外重要了. 首先需要有几个概念: 1.同步和异步 同步异步是来形容方法的一次调用的 ...
- IDEA 创建Web项目并在Tomcat中部署运行(转)
原文地址:https://www.cnblogs.com/tufujie/p/5738250.html IDEA 14.0.5 apache-tomcat-8.0.32 步骤:File->New ...
- ios获取系统时间
//获取系统时间 NSDate * date=[NSDate date]; NSDateFormatter *dateformatter=[[NSDateFormatter alloc] init]; ...
- 记一次内存泄漏调试(memory leak)-Driver Monkey
Author:DriverMonkey Mail:bookworepeng@Hotmail.com Phone:13410905075 QQ:196568501 硬件环境:AM335X 软件环境:li ...
- MFC的CListCtrl的使用与技巧
http://blog.csdn.net/artechtor/article/details/2508070 列表控件可以看作是功能增强的ListBox,它提供了四种风格,而且可以同时显示一列的多中属 ...
- 对touch事件传递的简单理解
对View事件传递的理解.看的这篇. 对事件传递有了大致的了解. onInterceptTouchEvent 函数决定是否将事件拦截,拦截之后,该控件的全部子控件接收不到这个事件.onTouchEve ...