|
23 | 23 | import java.util.List;
|
24 | 24 | import java.util.Map;
|
25 | 25 | import java.util.concurrent.atomic.AtomicReference;
|
26 |
| -import java.util.function.Supplier; |
| 26 | +import java.util.function.Function; |
27 | 27 |
|
28 | 28 | import jakarta.servlet.DispatcherType;
|
29 | 29 | import jakarta.servlet.ServletContext;
|
30 | 30 | import jakarta.servlet.ServletRegistration;
|
31 | 31 | import jakarta.servlet.http.HttpServletRequest;
|
| 32 | +import org.apache.commons.logging.Log; |
| 33 | +import org.apache.commons.logging.LogFactory; |
32 | 34 |
|
33 | 35 | import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
34 | 36 | import org.springframework.context.ApplicationContext;
|
|
44 | 46 | import org.springframework.security.web.util.matcher.RequestMatcher;
|
45 | 47 | import org.springframework.util.Assert;
|
46 | 48 | import org.springframework.util.ClassUtils;
|
47 |
| -import org.springframework.util.function.SingletonSupplier; |
48 | 49 | import org.springframework.web.context.WebApplicationContext;
|
49 | 50 | import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
|
50 | 51 |
|
@@ -76,6 +77,8 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
76 | 77 | AbstractRequestMatcherRegistry.class.getClassLoader());
|
77 | 78 | }
|
78 | 79 |
|
| 80 | + private final Log logger = LogFactory.getLog(getClass()); |
| 81 | + |
79 | 82 | protected final void setApplicationContext(ApplicationContext context) {
|
80 | 83 | this.context = context;
|
81 | 84 | }
|
@@ -209,7 +212,12 @@ public C requestMatchers(HttpMethod method, String... patterns) {
|
209 | 212 | matchers.add(resolve(ant, mvc, servletContext));
|
210 | 213 | }
|
211 | 214 | else {
|
212 |
| - matchers.add(new DeferredRequestMatcher(() -> resolve(ant, mvc, servletContext), mvc, ant)); |
| 215 | + this.logger |
| 216 | + .warn("The ServletRegistration API was not available at startup time. This may be due to a misconfiguration; " |
| 217 | + + "if you are using AbstractSecurityWebApplicationInitializer, please double-check the recommendations outlined in " |
| 218 | + + "https://docs.spring.io/spring-security/reference/servlet/configuration/java.html#abstractsecuritywebapplicationinitializer-with-spring-mvc"); |
| 219 | + matchers.add(new DeferredRequestMatcher((request) -> resolve(ant, mvc, request.getServletContext()), |
| 220 | + mvc, ant)); |
213 | 221 | }
|
214 | 222 | }
|
215 | 223 | return requestMatchers(matchers.toArray(new RequestMatcher[0]));
|
@@ -466,27 +474,34 @@ static List<RequestMatcher> regexMatchers(String... regexPatterns) {
|
466 | 474 |
|
467 | 475 | static class DeferredRequestMatcher implements RequestMatcher {
|
468 | 476 |
|
469 |
| - final Supplier<RequestMatcher> requestMatcher; |
| 477 | + final Function<HttpServletRequest, RequestMatcher> requestMatcherFactory; |
470 | 478 |
|
471 | 479 | final AtomicReference<String> description = new AtomicReference<>();
|
472 | 480 |
|
473 |
| - DeferredRequestMatcher(Supplier<RequestMatcher> resolver, RequestMatcher... candidates) { |
474 |
| - this.requestMatcher = SingletonSupplier.of(() -> { |
475 |
| - RequestMatcher matcher = resolver.get(); |
476 |
| - this.description.set(matcher.toString()); |
477 |
| - return matcher; |
478 |
| - }); |
| 481 | + volatile RequestMatcher requestMatcher; |
| 482 | + |
| 483 | + DeferredRequestMatcher(Function<HttpServletRequest, RequestMatcher> resolver, RequestMatcher... candidates) { |
| 484 | + this.requestMatcherFactory = (request) -> { |
| 485 | + if (this.requestMatcher == null) { |
| 486 | + synchronized (this) { |
| 487 | + if (this.requestMatcher == null) { |
| 488 | + this.requestMatcher = resolver.apply(request); |
| 489 | + } |
| 490 | + } |
| 491 | + } |
| 492 | + return this.requestMatcher; |
| 493 | + }; |
479 | 494 | this.description.set("Deferred " + Arrays.toString(candidates));
|
480 | 495 | }
|
481 | 496 |
|
482 | 497 | @Override
|
483 | 498 | public boolean matches(HttpServletRequest request) {
|
484 |
| - return this.requestMatcher.get().matches(request); |
| 499 | + return this.requestMatcherFactory.apply(request).matches(request); |
485 | 500 | }
|
486 | 501 |
|
487 | 502 | @Override
|
488 | 503 | public MatchResult matcher(HttpServletRequest request) {
|
489 |
| - return this.requestMatcher.get().matcher(request); |
| 504 | + return this.requestMatcherFactory.apply(request).matcher(request); |
490 | 505 | }
|
491 | 506 |
|
492 | 507 | @Override
|
|
0 commit comments