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


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

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

就会调用到之前说到的

1
2
3
4
5
6
7
8
9
10
11
12
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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

1
2
3
4
5
6
7
8
9
10
11
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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 接口

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

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

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

然后调用了 onStartup 方法,

1
2
3
4
5
6
7
8
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);
}

就会去执行注册逻辑