|
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 |
|
@@ -322,36 +323,15 @@ public C requestMatchers(HttpMethod method, String... patterns) {
|
322 | 323 | if (servletContext == null) {
|
323 | 324 | return requestMatchers(RequestMatchers.antMatchersAsArray(method, patterns));
|
324 | 325 | }
|
325 |
| - boolean isProgrammaticApiAvailable = isProgrammaticApiAvailable(servletContext); |
326 | 326 | List<RequestMatcher> matchers = new ArrayList<>();
|
327 | 327 | for (String pattern : patterns) {
|
328 | 328 | AntPathRequestMatcher ant = new AntPathRequestMatcher(pattern, (method != null) ? method.name() : null);
|
329 | 329 | MvcRequestMatcher mvc = createMvcMatchers(method, pattern).get(0);
|
330 |
| - if (isProgrammaticApiAvailable) { |
331 |
| - matchers.add(resolve(ant, mvc, servletContext)); |
332 |
| - } |
333 |
| - else { |
334 |
| - this.logger |
335 |
| - .warn("The ServletRegistration API was not available at startup time. This may be due to a misconfiguration; " |
336 |
| - + "if you are using AbstractSecurityWebApplicationInitializer, please double-check the recommendations outlined in " |
337 |
| - + "https://docs.spring.io/spring-security/reference/servlet/configuration/java.html#abstractsecuritywebapplicationinitializer-with-spring-mvc"); |
338 |
| - matchers.add(new DeferredRequestMatcher((request) -> resolve(ant, mvc, request.getServletContext()), |
339 |
| - mvc, ant)); |
340 |
| - } |
| 330 | + matchers.add(new DeferredRequestMatcher((c) -> resolve(ant, mvc, c), mvc, ant)); |
341 | 331 | }
|
342 | 332 | return requestMatchers(matchers.toArray(new RequestMatcher[0]));
|
343 | 333 | }
|
344 | 334 |
|
345 |
| - private static boolean isProgrammaticApiAvailable(ServletContext servletContext) { |
346 |
| - try { |
347 |
| - servletContext.getServletRegistrations(); |
348 |
| - return true; |
349 |
| - } |
350 |
| - catch (UnsupportedOperationException ex) { |
351 |
| - return false; |
352 |
| - } |
353 |
| - } |
354 |
| - |
355 | 335 | private RequestMatcher resolve(AntPathRequestMatcher ant, MvcRequestMatcher mvc, ServletContext servletContext) {
|
356 | 336 | Map<String, ? extends ServletRegistration> registrations = mappableServletRegistrations(servletContext);
|
357 | 337 | if (registrations.isEmpty()) {
|
@@ -593,34 +573,29 @@ static List<RequestMatcher> regexMatchers(String... regexPatterns) {
|
593 | 573 |
|
594 | 574 | static class DeferredRequestMatcher implements RequestMatcher {
|
595 | 575 |
|
596 |
| - final Function<HttpServletRequest, RequestMatcher> requestMatcherFactory; |
| 576 | + final Function<ServletContext, RequestMatcher> requestMatcherFactory; |
597 | 577 |
|
598 | 578 | final AtomicReference<String> description = new AtomicReference<>();
|
599 | 579 |
|
600 |
| - volatile RequestMatcher requestMatcher; |
601 |
| - |
602 |
| - DeferredRequestMatcher(Function<HttpServletRequest, RequestMatcher> resolver, RequestMatcher... candidates) { |
603 |
| - this.requestMatcherFactory = (request) -> { |
604 |
| - if (this.requestMatcher == null) { |
605 |
| - synchronized (this) { |
606 |
| - if (this.requestMatcher == null) { |
607 |
| - this.requestMatcher = resolver.apply(request); |
608 |
| - } |
609 |
| - } |
610 |
| - } |
611 |
| - return this.requestMatcher; |
612 |
| - }; |
| 580 | + final Map<ServletContext, RequestMatcher> requestMatchers = new ConcurrentHashMap<>(); |
| 581 | + |
| 582 | + DeferredRequestMatcher(Function<ServletContext, RequestMatcher> resolver, RequestMatcher... candidates) { |
| 583 | + this.requestMatcherFactory = (sc) -> this.requestMatchers.computeIfAbsent(sc, resolver); |
613 | 584 | this.description.set("Deferred " + Arrays.toString(candidates));
|
614 | 585 | }
|
615 | 586 |
|
| 587 | + RequestMatcher requestMatcher(ServletContext servletContext) { |
| 588 | + return this.requestMatcherFactory.apply(servletContext); |
| 589 | + } |
| 590 | + |
616 | 591 | @Override
|
617 | 592 | public boolean matches(HttpServletRequest request) {
|
618 |
| - return this.requestMatcherFactory.apply(request).matches(request); |
| 593 | + return this.requestMatcherFactory.apply(request.getServletContext()).matches(request); |
619 | 594 | }
|
620 | 595 |
|
621 | 596 | @Override
|
622 | 597 | public MatchResult matcher(HttpServletRequest request) {
|
623 |
| - return this.requestMatcherFactory.apply(request).matcher(request); |
| 598 | + return this.requestMatcherFactory.apply(request.getServletContext()).matcher(request); |
624 | 599 | }
|
625 | 600 |
|
626 | 601 | @Override
|
|
0 commit comments