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
12private 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
获取初始化所需要的 bean1
2
3protected 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
15public 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
11protected 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,添加到 initializers1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24protected <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
3for (ServletContextInitializer beans : getServletContextInitializerBeans()) {
beans.onStartup(servletContext);
}
在 for 循环中会把 Initializer 排序后的 sortedList 返回 iterator,也就是前面把 filter 包装成的 RegistrationBean1
2
3public Iterator<ServletContextInitializer> iterator() {
return this.sortedList.iterator();
}
然后调用了 onStartup 方法,1
2
3
4
5
6
7
8public 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);
}
就会去执行注册逻辑