ServletContextInitializer添加 servlet filter listener
ServletContextInitializer添加 servlet filter listener
https://www.cnblogs.com/pomer-huang/p/9639322.html
关于springboot中添加Filter的方法
https://www.jianshu.com/p/3d421fbce734
———————————————————————————————————————————————————————————————
Spring Boot Servlet : ServletContextInitializer
概述
功能介绍
Spring Boot
提供的在Servlet 3.0+
环境中用于程序化配置ServletContext
的接口。该接口ServletContextInitializer
主要被RegistrationBean
实现用于往ServletContext
容器中注册Servlet
,Filter
或者EventListener
。这些ServletContextInitializer
的设计目的主要是用于这些实例被Spring IoC
容器管理。这些ServletContextInitializer
实例不会被SpringServletContainerInitializer
检测,因此不会被Servlet
容器自动启动。
该接口
ServletContextInitializer
和Spring Web
的另外一个接口WebApplicationInitializer
看起来几乎一模一样。但二者使用目的不同。Spring Web
中,WebApplicationInitializer
也是针对Servlet 3.0+
环境,设计用于程序化配置ServletContext
,跟传统的web.xml
相对或者配合使用。WebApplicationInitializer
实现类会被SpringServletContainerInitializer
自动检测和启动。
继承关系
使用
关于ServletContextInitializer
的应用可以参考下面的例子。TomcatStarter
是Spring Boot Web Servlet
应用结合Tomcat
使用时的一个ServletContainerInitializer
实现。从下面代码不难看出,一组ServletContextInitializer
会被设置到ServletContainerInitializer TomcatStarter
上,而TomcatStarter
在Servlet
容器启动过程中调用自己的方法#onStartup
,会逐一调用这些ServletContextInitializer
的方法#onStartup
初始化ServletContext
。
package org.springframework.boot.web.embedded.tomcat;
import java.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.web.servlet.ServletContextInitializer;
class TomcatStarter implements ServletContainerInitializer {
private static final Log logger = LogFactory.getLog(TomcatStarter.class);
// 使用者会指定一组 ServletContextInitializer 给 TomcatStarter
private final ServletContextInitializer[] initializers;
private volatile Exception startUpException;
TomcatStarter(ServletContextInitializer[] initializers) {
this.initializers = initializers;
}
// Servlet 容器启动时回会用该方法,该方法会逐一调用每个 ServletContextInitializer 的方法
// #onStartup 会指定 ServletContext 进行初始化。这些 ServletContextInitializer 的目的
// 通常会是 注册 Servlet, Filter 或者 EventListener 。
@Override
public void onStartup(Set<Class<?>> classes, ServletContext servletContext)
throws ServletException {
try {
for (ServletContextInitializer initializer : this.initializers) {
initializer.onStartup(servletContext);
}
}
catch (Exception ex) {
this.startUpException = ex;
// Prevent Tomcat from logging and re-throwing when we know we can
// deal with it in the main thread, but log for information here.
if (logger.isErrorEnabled()) {
logger.error("Error starting Tomcat context. Exception: "
+ ex.getClass().getName() + ". Message: " + ex.getMessage());
}
}
}
public Exception getStartUpException() {
return this.startUpException;
}
}
源代码
源代码版本 : 2.1.3.RELEASE
package org.springframework.boot.web.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.web.SpringServletContainerInitializer;
import org.springframework.web.WebApplicationInitializer;
@FunctionalInterface
public interface ServletContextInitializer {
/**
* Configure the given ServletContext with any servlets, filters, listeners
* context-params and attributes necessary for initialization.
* @param servletContext the ServletContext to initialize
* @throws ServletException if any call against the given ServletContext
* throws a ServletException
*/
void onStartup(ServletContext servletContext) throws ServletException;
}
参考文章
——————————————————————————————————————————————————————————————————
springboot 2.1.3.RELEASE添加filter,servlet源码学习
Servlet规范中,通过ServeltContext来注册Filter、Servlet,这里分析Filter,Servlet是相同逻辑
springboot2.0中,我们通过
FilterRegistrationBean将指定得filter来实现ServeltContext注册filter
1
2
3
4
5
6
7
8
9
10
11
12
13
|
FilterRegistrationBean的实例化过程 public FilterRegistrationBean(T filter, ServletRegistrationBean... servletRegistrationBeans) { super (servletRegistrationBeans); Assert.notNull(filter, "Filter must not be null" ); this .filter = filter; } super 的实例化 AbstractFilterRegistrationBean(ServletRegistrationBean... servletRegistrationBeans) { Assert.notNull(servletRegistrationBeans, "ServletRegistrationBeans must not be null" ); Collections.addAll( this .servletRegistrationBeans, servletRegistrationBeans); } |
可知FilterRegistrationBean得实例化过程就是将Filter保存到servletRegistrationBeans(一个set)中
再分析FilterRegistrationBean类
FilterRegistrationBean的父类是一个ServletContextInitializer,他有一个方法onStartup(ServletContext servletContext)
其结果最终会调用
servletContext.addFilter(this.getOrDeduceName(filter), filter)
现在看看ServletContextInitializer.onStartup的调用地方
1
2
3
4
5
6
7
8
9
10
11
12
|
springboot启动 new SpringApplication(XXApplication. class ).run(XXApplication. class ,args) 调用 refreshContext(context); -> refresh(context); -> ((AbstractApplicationContext) applicationContext).refresh(); -> ServletWebServerApplicationContext.onRefresh(); -> createWebServer(); WebServer webServer = this .webServer; ServletContext servletContext = getServletContext(); if (webServer == null && servletContext == null ) { ServletWebServerFactory factory = getWebServerFactory(); this .webServer = factory.getWebServer(getSelfInitializer()); } |
再分析getSelfInitializer方法
1
2
3
4
|
prepareWebApplicationContext(servletContext); registerApplicationScope(servletContext); WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(),servletContext); for (ServletContextInitializer beans :getServletContextInitializerBeans()) { //调用ServletContextInitializer的onStartup方法 |
1
|
beans.onStartup(servletContext); } -> getServletContextInitializerBeans() |
1
2
|
-> new ServletContextInitializerBeans(getBeanFactory()) -> addAdaptableBeans(beanFactory) |
1
2
3
4
5
6
7
8
|
addAdaptableBeans(ListableBeanFactory beanFactory) 代码如下: MultipartConfigElement multipartConfig = getMultipartConfig(beanFactory); //将servlet类的bean包装为ServletRegistrationBean addAsRegistrationBean(beanFactory, Servlet. class , new ServletRegistrationBeanAdapter(multipartConfig)); //将Filter的bean包装为FilterRegistrationBean addAsRegistrationBean(beanFactory, Filter. class , new FilterRegistrationBeanAdapter()); for (Class<?> listenerType : ServletListenerRegistrationBean.getSupportedTypes()) { addAsRegistrationBean(beanFactory, EventListener. class ,(Class<EventListener>) listenerType, new ServletListenerRegistrationBeanAdapter()); } |
这里提一下,如果Servlet的bean实例名为dispatcherServlet,且该实例在seen集合中(seen集合为自定义配置的实例,通过ServletContextInitializerBeans.addServletContextInitializerBean入口可以查看源码),则设置默认值为 /
1
2
3
4
5
6
7
|
String url = (totalNumberOfSourceBeans != 1 ) ? "/" + name + "/" : "/" ; if (name.equals(DISPATCHER_SERVLET_NAME)) { url = "/" ; // always map the main dispatcherServlet to "/" } ServletRegistrationBean<Servlet> bean = new ServletRegistrationBean<>(source,url); bean.setName(name); bean.setMultipartConfig( this .multipartConfig); return bean; |
总结:springboot启动时,会将所有的 FilterRegistrationBean、ServletRegistrationBean以及被spring管理的Servlet和Filter的实例,通过 ServletContext注册Servlet以及Filter
ServletContextInitializer添加 servlet filter listener的更多相关文章
- SpringBoot学习笔记(6)----SpringBoot中使用Servlet,Filter,Listener的三种方式
在一般的运用开发中Controller已经大部分都能够实现了,但是也不排除需要自己实现Servlet,Filter,Listener的方式,SpringBoot提供了三种实现方式. 1. 使用Bean ...
- JavaWeb三大组件(Servlet,Filter,Listener 自己整理,初学者可以借鉴一下)
JavaWeb三大组件(Servlet,Filter,Listener 自己整理,初学者可以借鉴一下) Reference
- SpringBoot---注册Servlet,Filter,Listener
1.概述 1.1.当使用 内嵌的Servlet容器(Tomcat.Jetty等)时,将Servlet,Filter,Listener 注册到Servlet容器的方法: 1.1.1.直接注册Bean ...
- servlet filter listener interceptor 知识点
这篇文章主要介绍 servlet filter listener interceptor 之 知识点.博文主要从 概念,生命周期,使命介绍其区别.详情如下: 概念 生命周期 使命 servlet ...
- servlet/filter/listener/interceptor区别与联系
转自:http://www.cnblogs.com/doit8791/p/4209442.html servlet.filter.listener是配置到web.xml中(web.xml 的加载顺序是 ...
- 【转】servlet/filter/listener/interceptor区别与联系
原文:https://www.cnblogs.com/doit8791/p/4209442.html 一.概念: 1.servlet:servlet是一种运行服务器端的java应用程序,具有独立于平台 ...
- [转]web.xml中servlet ,filter ,listener ,interceptor的作用与区别
原文链接:https://blog.csdn.net/netdevgirl/article/details/51483273 一.概念: 1.servlet:servlet是一种运行服务器端的java ...
- SpringBoot整合WEB开发--(九)整合Servlet,Filter,Listener
简介: 如果需要整合第三方框架时,可能还是不得不使用Servlet,Filter,Listener,Springboot中也有提供支持. @WebServlet("/my") pu ...
- Spring Boot整合Servlet,Filter,Listener,访问静态资源
目录 Spring Boot整合Servlet(两种方式) 第一种方式(通过注解扫描方式完成Servlet组件的注册): 第二种方式(通过方法完成Servlet组件的注册) Springboot整合F ...
随机推荐
- 【13NOIP提高组】转圈游戏(信息学奥赛一本通 1875)(洛谷 1965)
题目描述 nn 个小描述 n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从0 到 n-1.最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 1 号 ...
- 怎么让input默认为0
<span class="item_title">供应商定金</span> <div class="flex-fill flex" ...
- 查看大图、html查看大图、js查看大图
$(".pimg").click(function(){ var _this = $(this);//将当前的pimg元素作为_this传入函数 imgShow("#ou ...
- 使用MeadCo's ScriptX控件做WEB打印
官方网址:http://www.meadroid.com/scriptx/index.asp MeadCo's ScriptX控件有两种使用方式,一种是做为免费版本使用,一种是做为收费版本使用,免费版 ...
- SEAndroid
SEAndroid安全机制所要保护的对象是系统中的资源,这些资源分布在各个子系统中,例如我们经常接触的文件就是分布文件子系统中的. 实际上,系统中需要保护的资源非常多,除了前面说的文件之外,还有进程. ...
- python测试mysql数据库性能(二)
一,普通写入数据库 二,批量写入数据库 三,普通写入数据库添加事务 config = { 'host': 'localhost', 'port': 3306, 'database': 'test', ...
- [linux]查看进程占用内存
1.top -p 进程ID PID:进程的ID USER:进程所有者 PR:进程的优先级别,越小越优先被执行 NInice:值 VIRT:进程占用的虚拟内存 RES:进程占用的物理内存 SHR:进程使 ...
- 树莓派小用手册(安装系统,配置图形界面,连接WiFi,调用摄像头,安装ffmpeg)
安装树莓派系统(重装) 准备工作: 安装需要干净的TF卡(最好 8G 以上),如果是重装的话,需要先将其清理后再使用.清理步骤下面会给出,清理需要工具 DiskGenius,下载链接:http://w ...
- LeetCode 110. Balanced Binary Tree(判断平衡二叉树)
Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary ...
- conda进行python环境隔离
1.环境隔离的问题 在使用python时,常常遇到的问题: pip安装库A,依赖库B-2.1版本 pip安装库C,以来库B-3.1版本,安装会提示库B的版本冲突错误. 这种情况下就需要做环境隔离 co ...