spring boot中如何加载servlet和filter

ServletContextInitializer

用于程序化配置ServletContext的接口,用于往ServletContext容器中注册servlets, filters, listeners,context-params and attributes
初始化tomcat服务器时,会初始TomcatStarter(实现ServletContainerInitializer接口)并在其中存放当前系统存在的ServletContextInitializer,在StandardContext的start启动时调用TomcatStarter的startup方法

public interface ServletContextInitializer {
	void onStartup(ServletContext servletContext) throws ServletException;
}
  1. onStartup方法

为当前IOC容器设置servletContext
注册ServletContext的作用域和环境变量
寻找当前系统

private void selfInitialize(ServletContext servletContext) throws ServletException {
	// 为当前应用上下文设置servletContext
	prepareWebApplicationContext(servletContext);
	// 注册ServletContext的作用域
	registerApplicationScope(servletContext);
	// 向给定的BeanFactory注册特定于web的环境bean->("contextParameters", "contextAttributes")
	WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), servletContext);
	// 获得ServletContextInitializerBeans类,遍历其中ServletContextInitializer
	for (ServletContextInitializer beans : getServletContextInitializerBeans()) {
		beans.onStartup(servletContext);
	}
}
  1. ServletContextInitializerBeans的构造方法,在创建webServer时调用

从当前IOC容器中寻找实现了ServletContextInitializer接口的类,添加到当前initializers中,如dispatcherServletRegistration、securityFilterChainRegistration
添加当前容器中存在的Servlet、Filter和EventListener类,并使用适配器模式将其转换为RegistrationBean类型
对初始化器排序

public ServletContextInitializerBeans(ListableBeanFactory beanFactory,
			Class<? extends ServletContextInitializer>... initializerTypes) {
	this.initializers = new LinkedMultiValueMap<>();
	this.initializerTypes = (initializerTypes.length != 0) ? Arrays.asList(initializerTypes)
			: Collections.singletonList(ServletContextInitializer.class);
	// 从当前IOC容器中寻找实现了ServletContextInitializer接口的类,添加到当前initializers中(Servlet.class,Filter.class,EventListener.class)
	addServletContextInitializerBeans(beanFactory);
	// 添加当前容器中存在的Servlet、Filter和EventListener类,并使用适配器模式将其转换为RegistrationBean类型
	addAdaptableBeans(beanFactory);
	// 对初始化器排序
	List<ServletContextInitializer> sortedInitializers = this.initializers.values().stream()
			.flatMap((value) -> value.stream().sorted(AnnotationAwareOrderComparator.INSTANCE))
			.collect(Collectors.toList());
	this.sortedList = Collections.unmodifiableList(sortedInitializers);
	logMappings(this.initializers);
}
  1. ServletRegistrationBean向StandardContext中注册Servlet
public final void onStartup(ServletContext servletContext) throws ServletException {
	String description = getDescription();
	···日志
	register(description, servletContext);
}

protected final void register(String description, ServletContext servletContext) {
	// 注册Servlet对象
	D registration = addRegistration(description, servletContext);
	···日志
	// 配置映射 / -> servlet
	configure(registration);
}

filter的执行

组件

FilterChain

用于管理特定请求的一组过滤器的执行

public interface FilterChain {
	public void doFilter(ServletRequest request, ServletResponse response)
            throws IOException, ServletException;
}
ApplicationFilterChain

Tomcat中的过滤器链实现

public final class ApplicationFilterChain implements FilterChain {
	// 持有的过滤器,从StandardContext中获取
	private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];
	// 过滤后调用的Servlet
	private Servlet servlet = null;
	// 当前过滤器在过滤器链中的位置
	private int pos = 0;
	// 总个数,根据pos和n来判断是否过滤完成
	private int n = 0;
}
FilterDef

过滤器的定义

public class FilterDef implements Serializable {
	// 过滤器描述
	private String description = null;
	private String displayName = null;
	// 过滤器实例
	private transient Filter filter = null;
	// 过滤器全限制名称
	private String filterClass = null;
	// 过滤器名称
	private String filterName = null;
}	
FilterMap

保存filter名称与url的映射

ApplicationFilterConfig

一个过滤器配置对象,由servlet容器在初始化期间将信息传递给过滤器

public final class ApplicationFilterConfig implements FilterConfig, Serializable {
	private final transient Context context;
	private final FilterDef filterDef;
}
StandardContext中与filter关联的字段

private Map<String, FilterDef> filterDefs = new HashMap<>();
private final ContextFilterMaps filterMaps = new ContextFilterMaps();
private Map<String, ApplicationFilterConfig> filterConfigs = new HashMap<>();

Spring Boot中流程

  1. context启动时,调用ServletContainerInitializers添加filter,调用AbstractFilterRegistrationBean类的addRegistration方法向context添加filter
  2. context中不存在FilterDef则创建对应FilterDef
  3. AbstractFilterRegistrationBean中configure方法添加匹配filter的uri,默认为/*
  4. context启动时,调用filterStart方法配置初始化ApplicationFilterConfig
  5. 调用filter的init方法
  6. 对每次到达的请求在StandardWrapperVavel的invoke方法中创建过滤器链
  7. 根据名称获得ApplicationFilterConfig添加到过滤器链,通过ApplicationFilterConfig来获取filter执行
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值