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 ...
随机推荐
- manjaro系统的回滚操作
作为linux系统的爱好者,自从使用linux后,就喜欢追求新的软件,连系统都换成了滚动升级的版本.manjaro基于arch linux,同时也是kde的支持系统,升级非常频繁.使用了几年,很少碰到 ...
- beforeDestroy的使用
beforeDestroy ---实例销毁之前调用 需求是这样的: important:下面截图数据都是测试数据 日期在我点击查询的时候要存储,刷新就读内存,但是我点击其他页面再进来的时候,这个内存要 ...
- sparkUI
sparkUI 源码: https://www.cnblogs.com/barrenlake/p/4364644.html 页面介绍: https://blog.csdn.net/qq_2763977 ...
- spring @Transactional 事务注解的坑
1. 在需要事务管理的地方加@Transactional 注解.@Transactional 注解可以被应用于接口定义和接口方法.类定义和类的 public 方法上. 2. @Transactiona ...
- centos安装redis 5.0版本的集群
我在本地VM-Centos里安装5.0.5时安装遇到了些问题,参考了Blog:https://www.cnblogs.com/shawhe/p/9548620.html 顺利安装完成. 安装redis ...
- PostgreSQL中的The Oversized-Attribute Storage Technique(TOAST:超大属性存储技术)
PostgreSQL使用固定的页面大小(通常为8kB),并且不允许元组跨越多个页面.因此,不可能直接存储非常大的字段值.为了克服这种限制,将大字段值压缩和/或分解成多个物理行.这对用户来说是透明的,对 ...
- 如何解决“HttpException (0x80004005): 超过了最大请求长度”问题
.net mvc项目在做上传文件时,出现这个问题,上传文件的是通过表单提交,后台是通过请求里面获取文件信息的 1.问题截图: 堆栈信息 “/”应用程序中的服务器错误.超过了最大请求长度.说明: 执行当 ...
- swoole流程图
程图,便于以后回忆下 总结几点如下: 首先主进程监听pipe_master事件, 子进程监听pipe_worker事件 通过主进程派生的线程 swReactorThread *thread = swS ...
- asp.net core项目 Nlog直接写入集群ElasticSearch的配置方法
1.NuGet 项目引用 NLog.Web.AspNetCore NLog.Targets.ElasticSearch 2.nlog.config配置文件: <?xml version=&quo ...
- ajax提交json数据到后端C#解析
本文链接:https://blog.csdn.net/qq_22103321/article/details/78015920 前端提交json数据 $.ajax({ type: "post ...