|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2023 the original author or authors. |
| 2 | + * Copyright 2002-2024 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
22 | 22 | import java.util.LinkedHashMap;
|
23 | 23 | import java.util.List;
|
24 | 24 | import java.util.Map;
|
| 25 | +import java.util.concurrent.ConcurrentHashMap; |
25 | 26 | import java.util.concurrent.atomic.AtomicReference;
|
26 | 27 | import java.util.function.Function;
|
27 | 28 |
|
@@ -203,36 +204,15 @@ public C requestMatchers(HttpMethod method, String... patterns) {
|
203 | 204 | if (servletContext == null) {
|
204 | 205 | return requestMatchers(RequestMatchers.antMatchersAsArray(method, patterns));
|
205 | 206 | }
|
206 |
| - boolean isProgrammaticApiAvailable = isProgrammaticApiAvailable(servletContext); |
207 | 207 | List<RequestMatcher> matchers = new ArrayList<>();
|
208 | 208 | for (String pattern : patterns) {
|
209 | 209 | AntPathRequestMatcher ant = new AntPathRequestMatcher(pattern, (method != null) ? method.name() : null);
|
210 | 210 | MvcRequestMatcher mvc = createMvcMatchers(method, pattern).get(0);
|
211 |
| - if (isProgrammaticApiAvailable) { |
212 |
| - matchers.add(resolve(ant, mvc, servletContext)); |
213 |
| - } |
214 |
| - else { |
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)); |
221 |
| - } |
| 211 | + matchers.add(new DeferredRequestMatcher((c) -> resolve(ant, mvc, c), mvc, ant)); |
222 | 212 | }
|
223 | 213 | return requestMatchers(matchers.toArray(new RequestMatcher[0]));
|
224 | 214 | }
|
225 | 215 |
|
226 |
| - private static boolean isProgrammaticApiAvailable(ServletContext servletContext) { |
227 |
| - try { |
228 |
| - servletContext.getServletRegistrations(); |
229 |
| - return true; |
230 |
| - } |
231 |
| - catch (UnsupportedOperationException ex) { |
232 |
| - return false; |
233 |
| - } |
234 |
| - } |
235 |
| - |
236 | 216 | private RequestMatcher resolve(AntPathRequestMatcher ant, MvcRequestMatcher mvc, ServletContext servletContext) {
|
237 | 217 | Map<String, ? extends ServletRegistration> registrations = mappableServletRegistrations(servletContext);
|
238 | 218 | if (registrations.isEmpty()) {
|
@@ -474,34 +454,29 @@ static List<RequestMatcher> regexMatchers(String... regexPatterns) {
|
474 | 454 |
|
475 | 455 | static class DeferredRequestMatcher implements RequestMatcher {
|
476 | 456 |
|
477 |
| - final Function<HttpServletRequest, RequestMatcher> requestMatcherFactory; |
| 457 | + final Function<ServletContext, RequestMatcher> requestMatcherFactory; |
478 | 458 |
|
479 | 459 | final AtomicReference<String> description = new AtomicReference<>();
|
480 | 460 |
|
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 |
| - }; |
| 461 | + final Map<ServletContext, RequestMatcher> requestMatchers = new ConcurrentHashMap<>(); |
| 462 | + |
| 463 | + DeferredRequestMatcher(Function<ServletContext, RequestMatcher> resolver, RequestMatcher... candidates) { |
| 464 | + this.requestMatcherFactory = (sc) -> this.requestMatchers.computeIfAbsent(sc, resolver); |
494 | 465 | this.description.set("Deferred " + Arrays.toString(candidates));
|
495 | 466 | }
|
496 | 467 |
|
| 468 | + RequestMatcher requestMatcher(ServletContext servletContext) { |
| 469 | + return this.requestMatcherFactory.apply(servletContext); |
| 470 | + } |
| 471 | + |
497 | 472 | @Override
|
498 | 473 | public boolean matches(HttpServletRequest request) {
|
499 |
| - return this.requestMatcherFactory.apply(request).matches(request); |
| 474 | + return this.requestMatcherFactory.apply(request.getServletContext()).matches(request); |
500 | 475 | }
|
501 | 476 |
|
502 | 477 | @Override
|
503 | 478 | public MatchResult matcher(HttpServletRequest request) {
|
504 |
| - return this.requestMatcherFactory.apply(request).matcher(request); |
| 479 | + return this.requestMatcherFactory.apply(request.getServletContext()).matcher(request); |
505 | 480 | }
|
506 | 481 |
|
507 | 482 | @Override
|
|
0 commit comments