Make WebMvcMetricsFilter lazy

Update `WebMvcMetricsFilter` so that it no longer causes early
initialization of Spring MVC concerns.

Fixes gh-11571
pull/11498/merge
Phillip Webb 7 years ago
parent 19ce0aa4f0
commit cae02ce0b8

@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,10 +27,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
/**
* Configures instrumentation of Spring Web MVC servlet-based request mappings.
@ -60,9 +60,8 @@ public class WebMvcMetricsConfiguration {
}
@Bean
public WebMvcMetricsFilter webMetricsFilter(WebMvcMetrics controllerMetrics,
HandlerMappingIntrospector introspector) {
return new WebMvcMetricsFilter(controllerMetrics, introspector);
public WebMvcMetricsFilter webMetricsFilter(ApplicationContext context) {
return new WebMvcMetricsFilter(context);
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,6 +26,7 @@ import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.filter.OncePerRequestFilter;
@ -47,14 +48,14 @@ public class WebMvcMetricsFilter extends OncePerRequestFilter {
private static final Logger logger = LoggerFactory
.getLogger(WebMvcMetricsFilter.class);
private final WebMvcMetrics webMvcMetrics;
private final ApplicationContext context;
private final HandlerMappingIntrospector mappingIntrospector;
private volatile WebMvcMetrics webMvcMetrics;
public WebMvcMetricsFilter(WebMvcMetrics webMvcMetrics,
HandlerMappingIntrospector mappingIntrospector) {
this.webMvcMetrics = webMvcMetrics;
this.mappingIntrospector = mappingIntrospector;
private volatile HandlerMappingIntrospector mappingIntrospector;
public WebMvcMetricsFilter(ApplicationContext context) {
this.context = context;
}
@Override
@ -74,7 +75,7 @@ public class WebMvcMetricsFilter extends OncePerRequestFilter {
private HandlerExecutionChain getHandlerExecutionChain(HttpServletRequest request) {
try {
MatchableHandlerMapping matchableHandlerMapping = this.mappingIntrospector
MatchableHandlerMapping matchableHandlerMapping = getMappingIntrospector()
.getMatchableHandlerMapping(request);
return (matchableHandlerMapping == null ? null
: matchableHandlerMapping.getHandler(request));
@ -90,19 +91,35 @@ public class WebMvcMetricsFilter extends OncePerRequestFilter {
private void filterWithMetrics(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain, Object handler)
throws IOException, ServletException {
this.webMvcMetrics.preHandle(request, handler);
WebMvcMetrics metrics = getWebMvcMetrics();
metrics.preHandle(request, handler);
try {
filterChain.doFilter(request, response);
// When an async operation is complete, the whole filter gets called again
// with isAsyncStarted = false
if (!request.isAsyncStarted()) {
this.webMvcMetrics.record(request, response, null);
metrics.record(request, response, null);
}
}
catch (NestedServletException ex) {
this.webMvcMetrics.record(request, response, ex.getCause());
metrics.record(request, response, ex.getCause());
throw ex;
}
}
private HandlerMappingIntrospector getMappingIntrospector() {
if (this.mappingIntrospector == null) {
this.mappingIntrospector = this.context
.getBean(HandlerMappingIntrospector.class);
}
return this.mappingIntrospector;
}
private WebMvcMetrics getWebMvcMetrics() {
if (this.webMvcMetrics == null) {
this.webMvcMetrics = this.context.getBean(WebMvcMetrics.class);
}
return this.webMvcMetrics;
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,6 +26,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@ -39,7 +40,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@ -104,9 +104,8 @@ public class WebMvcMetricsFilterAutoTimedTests {
}
@Bean
public WebMvcMetricsFilter webMetricsFilter(WebMvcMetrics controllerMetrics,
HandlerMappingIntrospector introspector) {
return new WebMvcMetricsFilter(controllerMetrics, introspector);
public WebMvcMetricsFilter webMetricsFilter(ApplicationContext context) {
return new WebMvcMetricsFilter(context);
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -39,6 +39,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@ -58,7 +59,6 @@ import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
@ -237,9 +237,8 @@ public class WebMvcMetricsFilterTests {
}
@Bean
public WebMvcMetricsFilter webMetricsFilter(WebMvcMetrics controllerMetrics,
HandlerMappingIntrospector introspector) {
return new WebMvcMetricsFilter(controllerMetrics, introspector);
public WebMvcMetricsFilter webMetricsFilter(ApplicationContext context) {
return new WebMvcMetricsFilter(context);
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -28,6 +28,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
@ -43,7 +44,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
@ -119,9 +119,8 @@ public class WebMvcMetricsIntegrationTests {
}
@Bean
public WebMvcMetricsFilter webMetricsFilter(WebMvcMetrics controllerMetrics,
HandlerMappingIntrospector introspector) {
return new WebMvcMetricsFilter(controllerMetrics, introspector);
public WebMvcMetricsFilter webMetricsFilter(ApplicationContext context) {
return new WebMvcMetricsFilter(context);
}
@RestController

Loading…
Cancel
Save