Skip to content

Commit cae02ce

Browse files
committed
Make WebMvcMetricsFilter lazy
Update `WebMvcMetricsFilter` so that it no longer causes early initialization of Spring MVC concerns. Fixes gh-11571
1 parent 19ce0aa commit cae02ce

File tree

5 files changed

+44
-31
lines changed

5 files changed

+44
-31
lines changed

Diff for: spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/servlet/WebMvcMetricsConfiguration.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,10 +27,10 @@
2727
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2828
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
2929
import org.springframework.boot.context.properties.EnableConfigurationProperties;
30+
import org.springframework.context.ApplicationContext;
3031
import org.springframework.context.annotation.Bean;
3132
import org.springframework.context.annotation.Configuration;
3233
import org.springframework.web.servlet.DispatcherServlet;
33-
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
3434

3535
/**
3636
* Configures instrumentation of Spring Web MVC servlet-based request mappings.
@@ -60,9 +60,8 @@ public WebMvcMetrics controllerMetrics(MeterRegistry registry,
6060
}
6161

6262
@Bean
63-
public WebMvcMetricsFilter webMetricsFilter(WebMvcMetrics controllerMetrics,
64-
HandlerMappingIntrospector introspector) {
65-
return new WebMvcMetricsFilter(controllerMetrics, introspector);
63+
public WebMvcMetricsFilter webMetricsFilter(ApplicationContext context) {
64+
return new WebMvcMetricsFilter(context);
6665
}
6766

6867
}

Diff for: spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilter.java

+28-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
2626
import org.slf4j.Logger;
2727
import org.slf4j.LoggerFactory;
2828

29+
import org.springframework.context.ApplicationContext;
2930
import org.springframework.core.Ordered;
3031
import org.springframework.core.annotation.Order;
3132
import org.springframework.web.filter.OncePerRequestFilter;
@@ -47,14 +48,14 @@ public class WebMvcMetricsFilter extends OncePerRequestFilter {
4748
private static final Logger logger = LoggerFactory
4849
.getLogger(WebMvcMetricsFilter.class);
4950

50-
private final WebMvcMetrics webMvcMetrics;
51+
private final ApplicationContext context;
5152

52-
private final HandlerMappingIntrospector mappingIntrospector;
53+
private volatile WebMvcMetrics webMvcMetrics;
5354

54-
public WebMvcMetricsFilter(WebMvcMetrics webMvcMetrics,
55-
HandlerMappingIntrospector mappingIntrospector) {
56-
this.webMvcMetrics = webMvcMetrics;
57-
this.mappingIntrospector = mappingIntrospector;
55+
private volatile HandlerMappingIntrospector mappingIntrospector;
56+
57+
public WebMvcMetricsFilter(ApplicationContext context) {
58+
this.context = context;
5859
}
5960

6061
@Override
@@ -74,7 +75,7 @@ protected void doFilterInternal(HttpServletRequest request,
7475

7576
private HandlerExecutionChain getHandlerExecutionChain(HttpServletRequest request) {
7677
try {
77-
MatchableHandlerMapping matchableHandlerMapping = this.mappingIntrospector
78+
MatchableHandlerMapping matchableHandlerMapping = getMappingIntrospector()
7879
.getMatchableHandlerMapping(request);
7980
return (matchableHandlerMapping == null ? null
8081
: matchableHandlerMapping.getHandler(request));
@@ -90,19 +91,35 @@ private HandlerExecutionChain getHandlerExecutionChain(HttpServletRequest reques
9091
private void filterWithMetrics(HttpServletRequest request,
9192
HttpServletResponse response, FilterChain filterChain, Object handler)
9293
throws IOException, ServletException {
93-
this.webMvcMetrics.preHandle(request, handler);
94+
WebMvcMetrics metrics = getWebMvcMetrics();
95+
metrics.preHandle(request, handler);
9496
try {
9597
filterChain.doFilter(request, response);
9698
// When an async operation is complete, the whole filter gets called again
9799
// with isAsyncStarted = false
98100
if (!request.isAsyncStarted()) {
99-
this.webMvcMetrics.record(request, response, null);
101+
metrics.record(request, response, null);
100102
}
101103
}
102104
catch (NestedServletException ex) {
103-
this.webMvcMetrics.record(request, response, ex.getCause());
105+
metrics.record(request, response, ex.getCause());
104106
throw ex;
105107
}
106108
}
107109

110+
private HandlerMappingIntrospector getMappingIntrospector() {
111+
if (this.mappingIntrospector == null) {
112+
this.mappingIntrospector = this.context
113+
.getBean(HandlerMappingIntrospector.class);
114+
}
115+
return this.mappingIntrospector;
116+
}
117+
118+
private WebMvcMetrics getWebMvcMetrics() {
119+
if (this.webMvcMetrics == null) {
120+
this.webMvcMetrics = this.context.getBean(WebMvcMetrics.class);
121+
}
122+
return this.webMvcMetrics;
123+
}
124+
108125
}

Diff for: spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilterAutoTimedTests.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
2626
import org.junit.runner.RunWith;
2727

2828
import org.springframework.beans.factory.annotation.Autowired;
29+
import org.springframework.context.ApplicationContext;
2930
import org.springframework.context.annotation.Bean;
3031
import org.springframework.context.annotation.Configuration;
3132
import org.springframework.context.annotation.Import;
@@ -39,7 +40,6 @@
3940
import org.springframework.web.bind.annotation.RestController;
4041
import org.springframework.web.context.WebApplicationContext;
4142
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
42-
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
4343

4444
import static org.assertj.core.api.Assertions.assertThat;
4545
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -104,9 +104,8 @@ public WebMvcMetrics controllerMetrics(MeterRegistry registry) {
104104
}
105105

106106
@Bean
107-
public WebMvcMetricsFilter webMetricsFilter(WebMvcMetrics controllerMetrics,
108-
HandlerMappingIntrospector introspector) {
109-
return new WebMvcMetricsFilter(controllerMetrics, introspector);
107+
public WebMvcMetricsFilter webMetricsFilter(ApplicationContext context) {
108+
return new WebMvcMetricsFilter(context);
110109
}
111110

112111
}

Diff for: spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilterTests.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -39,6 +39,7 @@
3939
import org.junit.runner.RunWith;
4040

4141
import org.springframework.beans.factory.annotation.Autowired;
42+
import org.springframework.context.ApplicationContext;
4243
import org.springframework.context.annotation.Bean;
4344
import org.springframework.context.annotation.Configuration;
4445
import org.springframework.context.annotation.Import;
@@ -58,7 +59,6 @@
5859
import org.springframework.web.filter.OncePerRequestFilter;
5960
import org.springframework.web.servlet.ModelAndView;
6061
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
61-
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
6262

6363
import static org.assertj.core.api.Assertions.assertThat;
6464
import static org.assertj.core.api.Assertions.assertThatCode;
@@ -237,9 +237,8 @@ public WebMvcMetrics controllerMetrics(MeterRegistry registry) {
237237
}
238238

239239
@Bean
240-
public WebMvcMetricsFilter webMetricsFilter(WebMvcMetrics controllerMetrics,
241-
HandlerMappingIntrospector introspector) {
242-
return new WebMvcMetricsFilter(controllerMetrics, introspector);
240+
public WebMvcMetricsFilter webMetricsFilter(ApplicationContext context) {
241+
return new WebMvcMetricsFilter(context);
243242
}
244243

245244
}

Diff for: spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsIntegrationTests.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@
2828
import org.junit.runner.RunWith;
2929

3030
import org.springframework.beans.factory.annotation.Autowired;
31+
import org.springframework.context.ApplicationContext;
3132
import org.springframework.context.annotation.Bean;
3233
import org.springframework.context.annotation.Configuration;
3334
import org.springframework.http.HttpStatus;
@@ -43,7 +44,6 @@
4344
import org.springframework.web.bind.annotation.RestController;
4445
import org.springframework.web.context.WebApplicationContext;
4546
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
46-
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
4747

4848
import static org.assertj.core.api.Assertions.assertThat;
4949
import static org.assertj.core.api.Assertions.assertThatCode;
@@ -119,9 +119,8 @@ public WebMvcMetrics controllerMetrics(MeterRegistry registry) {
119119
}
120120

121121
@Bean
122-
public WebMvcMetricsFilter webMetricsFilter(WebMvcMetrics controllerMetrics,
123-
HandlerMappingIntrospector introspector) {
124-
return new WebMvcMetricsFilter(controllerMetrics, introspector);
122+
public WebMvcMetricsFilter webMetricsFilter(ApplicationContext context) {
123+
return new WebMvcMetricsFilter(context);
125124
}
126125

127126
@RestController

0 commit comments

Comments
 (0)