springboot 2.1.3.RELEASE添加filter,servlet源码学习
Servlet规范中,通过ServeltContext来注册Filter、Servlet,这里分析Filter,Servlet是相同逻辑
springboot2.0中,我们通过
FilterRegistrationBean将指定得filter来实现ServeltContext注册filter
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的调用地方
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方法
prepareWebApplicationContext(servletContext);
registerApplicationScope(servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(),servletContext);
for (ServletContextInitializer beans :getServletContextInitializerBeans()) {
//调用ServletContextInitializer的onStartup方法
beans.onStartup(servletContext);
}
-> getServletContextInitializerBeans()
-> new ServletContextInitializerBeans(getBeanFactory())
-> addAdaptableBeans(beanFactory)
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入口可以查看源码),则设置默认值为 /
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
如果不希望filter自动注册,可以通过以下方式:
@Bean
public FilterRegistrationBean registration(@Qualifier("loginFilter") LoginFilter loginFilter) {
FilterRegistrationBean registration = new FilterRegistrationBean(loginFilter);
registration.setEnabled(false);
return registration;
}
springboot 2.1.3.RELEASE添加filter,servlet源码学习的更多相关文章
- SpringBoot源码学习系列之嵌入式Servlet容器
目录 1.博客前言简单介绍 2.定制servlet容器 3.变换servlet容器 4.servlet容器启动原理 SpringBoot源码学习系列之嵌入式Servlet容器启动原理 @ 1.博客前言 ...
- 源码学习系列之SpringBoot自动配置(篇二)
源码学习系列之SpringBoot自动配置(篇二)之HttpEncodingAutoConfiguration 源码分析 继上一篇博客源码学习系列之SpringBoot自动配置(篇一)之后,本博客继续 ...
- SpringBoot源码学习系列之SpringMVC自动配置
目录 1.ContentNegotiatingViewResolver 2.静态资源 3.自动注册 Converter, GenericConverter, and Formatter beans. ...
- Spring源码学习:第1步--在Spring源码中添加最简单的Demo代码
为了最大程度地贴近Spring源码并进行学习,一种比较直接的做法是:直接在Spring源码中加入Demo代码,并进行调试. 参照以前使用Spring的经验,Spring最简单的使用方法是:一个实体类. ...
- XJar: Spring-Boot JAR 包加/解密工具,避免源码泄露以及反编译
XJar: Spring-Boot JAR 包加/解密工具,避免源码泄露以及反编译 <?xml version="1.0" encoding="UTF-8" ...
- 源码学习系列之SpringBoot自动配置(篇一)
源码学习系列之SpringBoot自动配置源码学习(篇一) ok,本博客尝试跟一下Springboot的自动配置源码,做一下笔记记录,自动配置是Springboot的一个很关键的特性,也容易被忽略的属 ...
- SpringBoot源码学习系列之异常处理自动配置
SpringBoot源码学习系列之异常处理自动配置 1.源码学习 先给个SpringBoot中的异常例子,假如访问一个错误链接,让其返回404页面 在浏览器访问: 而在其它的客户端软件,比如postm ...
- SpringBoot源码学习1——SpringBoot自动装配源码解析+Spring如何处理配置类的
系列文章目录和关于我 一丶什么是SpringBoot自动装配 SpringBoot通过SPI的机制,在我们程序员引入一些starter之后,扫描外部引用 jar 包中的META-INF/spring. ...
- Servlet源码初探
年底,公司的事情告一段落,就来捣鼓一下这个Servlet源码,为下一步的spingmvc源码初探做准备 1.Servlet接口 public interface Servlet { void init ...
随机推荐
- 第09组 团队Git现场编程实战
组长博客链接 1.团队分工 团队成员 分工明细 王耀鑫 博客撰写,数据处理 陈志荣 前端界面,前端功能实现 陈超颖 前端界面,前端功能实现 沈梓耀 前端界面,前端功能实现 林明镇 数据处理 滕佳 前端 ...
- Atcoder Regular Contest 060 F题第一问答案证明
一切的开始 令 \(x\) 为字符串,\(p\) 为正整数.如果对于满足 \(0\le i<|x|−p\) 的任何整数 \(i\) 满足 \(x[i]=x[i+p]\),则 \(p\) 称为 \ ...
- hdoj - 1342 Lotto
Problem Description In a Lotto I have ever played, one has to select 6 numbers from the set {1,2,... ...
- IDEA实现SpringBoot热部署
1.pom.xml添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifac ...
- pip常用命令(转载)
用阿里云服务器,使用pip安装第三方库的时候卡的要死.所以我就想pip能不能安装本地的包. 找到了这篇博客: http://me.iblogc.com/2015/01/01/pip%E5%B8%B8% ...
- SQLServer 截取函数 substring函数
declare @name char(1000) --注意:char(10)为10位,要是位数小了会让数据出错 set @name='s{sss}fc{fggh}dghdf{cccs}x' selec ...
- Spark2-数据探索
freqItems sampleBy cov crosstab approxQuantitle boolmFilter 布隆选择器 corr 皮尔逊相关系数 countMinSketch Spark2 ...
- IfcWallStandardCase 构件吊装模拟
wall_node = (osg::Node*)(index_node->clone(osg::CopyOp::DEEP_COPY_ALL));vc_mobileCrane->tranMo ...
- CentOS7.4安装ipython
摘自:https://www.jianshu.com/p/aa93a0341c82 使用pip3安装ipython及其依赖包:pip3 install ipython在 .bashrc文件中添加环境变 ...
- 【各种误解解释】C-LODOP的三种角色及注册号
该简短问答是从现象和误解和相关作为分类,主要是注册角色和注册号使用等.之前的相关博文(该相关博也有些链接到的博文,按照大类区分):LODOP和C-LODOP注册与角色等简短问答[增强版]. 确认角色: ...