执行顺序
tomcat—>connect—>Filter::doFilter—>Servlet::doService
ApplicationFilterChain 调用filter 实现, filter 实现复又调用 ApplicationFilterChain,执行完 service 后,又会到 filter 实现的调用栈。
private void internalDoFilter(ServletRequest request,
ServletResponse response)
throws IOException, ServletException {
// Call the next filter if there is one
if (pos < n) {
ApplicationFilterConfig filterConfig = filters[pos++];
Filter filter = filterConfig.getFilter();
filter.doFilter(request, response, this);
return;
}
// We fell off the end of the chain -- call the servlet instance
servlet.service(request, response);
}
org.springframework.boot.web.servlet包
TomcatStarter(ServletContainerInitializer)—>
ServletWebServerApplicationContext—>ServletContextInitializerBeans#addAdaptableBeans
public ServletContextInitializerBeans(ListableBeanFactory beanFactory) {
this.initializers = new LinkedMultiValueMap<>();
addServletContextInitializerBeans(beanFactory);
addAdaptableBeans(beanFactory);
List<ServletContextInitializer> sortedInitializers = this.initializers.values()
.stream()
.flatMap((value) -> value.stream()
.sorted(AnnotationAwareOrderComparator.INSTANCE))
.collect(Collectors.toList());
this.sortedList = Collections.unmodifiableList(sortedInitializers);
}
private void addAdaptableBeans(ListableBeanFactory beanFactory) {
MultipartConfigElement multipartConfig = getMultipartConfig(beanFactory);
addAsRegistrationBean(beanFactory, Servlet.class,
new ServletRegistrationBeanAdapter(multipartConfig));
addAsRegistrationBean(beanFactory, Filter.class,
new FilterRegistrationBeanAdapter());
for (Class<?> listenerType : ServletListenerRegistrationBean
.getSupportedTypes()) {
addAsRegistrationBean(beanFactory, EventListener.class,
(Class<EventListener>) listenerType,
new ServletListenerRegistrationBeanAdapter());
}
}
@Component
@Slf4j
public class AppDemoFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("-----------application filter init----------------");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.info("--------pre filter----------");
chain.doFilter(request,response);
log.info("--------post filter----------");
}
@Override
public void destroy() {
log.info("-----------application filter destroy----------------");
}
}
@Bean
public FilterRegistrationBean<WebMvcMetricsFilter> webMvcMetricsFilter(
MeterRegistry registry, MetricsProperties properties,
WebMvcTagsProvider tagsProvider, WebApplicationContext context) {
Server serverProperties = properties.getWeb().getServer();
WebMvcMetricsFilter filter = new WebMvcMetricsFilter(context, registry,
tagsProvider, serverProperties.getRequestsMetricName(),
serverProperties.isAutoTimeRequests());
FilterRegistrationBean<WebMvcMetricsFilter> registration = new FilterRegistrationBean<>(
filter);
registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC);
return registration;
}