Tomcat 系列篇七-介绍下 Filter 注册逻辑


org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#createWebServer 的时候会调用

this.webServer = factory.getWebServer(getSelfInitializer());

就会调用到之前说到的

private org.springframework.boot.web.servlet.ServletContextInitializer getSelfInitializer() {
		return this::selfInitialize;
	}

	private void selfInitialize(ServletContext servletContext) throws ServletException {
		prepareWebApplicationContext(servletContext);
		registerApplicationScope(servletContext);
		WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), servletContext);
		for (ServletContextInitializer beans : getServletContextInitializerBeans()) {
			beans.onStartup(servletContext);
		}
	}

而这里有个
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#getServletContextInitializerBeans
获取初始化所需要的 bean

protected Collection<ServletContextInitializer> getServletContextInitializerBeans() {
	return new ServletContextInitializerBeans(getBeanFactory());
}

里面就是 new 了这个 org.springframework.boot.web.servlet.ServletContextInitializerBeans#ServletContextInitializerBeans

public ServletContextInitializerBeans(ListableBeanFactory beanFactory,
			Class<? extends ServletContextInitializer>... initializerTypes) {
		this.initializers = new LinkedMultiValueMap<>();
		this.initializerTypes = (initializerTypes.length != 0) ? Arrays.asList(initializerTypes)
				: Collections.singletonList(ServletContextInitializer.class);
        // 这里是添加 ServletContextInitializer
		addServletContextInitializerBeans(beanFactory);
        // filter 是在这里
		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);
	}

具体来看看 org.springframework.boot.web.servlet.ServletContextInitializerBeans#addAdaptableBeans

protected void addAdaptableBeans(ListableBeanFactory beanFactory) {
	MultipartConfigElement multipartConfig = getMultipartConfig(beanFactory);
       // 这里把 Servlet 作为 RegistrationBean
	addAsRegistrationBean(beanFactory, Servlet.class, new ServletRegistrationBeanAdapter(multipartConfig));
       // 这里把 Filter 作为 RegistrationBean
	addAsRegistrationBean(beanFactory, Filter.class, new FilterRegistrationBeanAdapter());
	for (Class<?> listenerType : ServletListenerRegistrationBean.getSupportedTypes()) {
		addAsRegistrationBean(beanFactory, EventListener.class, (Class<EventListener>) listenerType,
				new ServletListenerRegistrationBeanAdapter());
	}
}

里面是这两段逻辑,先从 beanfactory 里获取到该类型的 bean,然后包装成 RegistrationBean,添加到 initializers

protected <T> void addAsRegistrationBean(ListableBeanFactory beanFactory, Class<T> type,
		RegistrationBeanAdapter<T> adapter) {
	addAsRegistrationBean(beanFactory, type, type, adapter);
}

private <T, B extends T> void addAsRegistrationBean(ListableBeanFactory beanFactory, Class<T> type,
		Class<B> beanType, RegistrationBeanAdapter<T> adapter) {
	List<Map.Entry<String, B>> entries = getOrderedBeansOfType(beanFactory, beanType, this.seen);
	for (Entry<String, B> entry : entries) {
		String beanName = entry.getKey();
		B bean = entry.getValue();
		if (this.seen.add(bean)) {
			// One that we haven't already seen
			RegistrationBean registration = adapter.createRegistrationBean(beanName, bean, entries.size());
			int order = getOrder(bean);
			registration.setOrder(order);
			this.initializers.add(type, registration);
			if (logger.isTraceEnabled()) {
				logger.trace("Created " + type.getSimpleName() + " initializer for bean '" + beanName + "'; order="
						+ order + ", resource=" + getResourceDescription(beanName, beanFactory));
			}
		}
	}
}

然后再回到第一段,其中的循环里面,因为 ServletContextInitializerBeans 继承了 AbstractCollection 并且实现了 iterator 接口

for (ServletContextInitializer beans : getServletContextInitializerBeans()) {
			beans.onStartup(servletContext);
		}

在 for 循环中会把 Initializer 排序后的 sortedList 返回 iterator,也就是前面把 filter 包装成的 RegistrationBean

public Iterator<ServletContextInitializer> iterator() {
		return this.sortedList.iterator();
	}

然后调用了 onStartup 方法,

public final void onStartup(ServletContext servletContext) throws ServletException {
	String description = getDescription();
	if (!isEnabled()) {
		logger.info(StringUtils.capitalize(description) + " was not registered (disabled)");
		return;
	}
	register(description, servletContext);
}

就会去执行注册逻辑