Compare commits

...

318 Commits

Author SHA1 Message Date
Spring Builds 5ea8ba1b96 Release v5.3.23 2022-09-15 07:47:35 +00:00
rstoyanchev ae8b7973b4 Improve Javadoc on RequestEntity#getUrl
Closes gh-28930
2022-09-14 19:25:55 +01:00
Juergen Hoeller a7f430bda8 Upgrade to Checkstyle 10.3.3, RxJava 3.1.5, SmallRye Mutiny 1.7, HtmlUnit 2.64, JsonPath 2.7 2022-09-14 19:28:27 +02:00
Juergen Hoeller 5a781eeb54 Upgrade to RSocket 1.1.3, Netty 4.1.82, Tomcat 9.0.65, Undertow 2.2.19, Hibernate Validator 6.2.5 2022-09-14 18:42:04 +02:00
Sam Brannen a879d18c9c Reintroduce Caucho exclusion for 5.3.x
See gh-28876
2022-09-14 17:10:17 +02:00
Marc Wrobel ce49068ff9 Fix links in Javadoc and reference docs
- Fix broken links (by using a new URL, an alternative URL, or a
  Wayback Machine link)

- Use HTTPS where possible

- Remove https://issuetracker.springsource.com/browse/EBR-349: this
  link is dead and is also mentioned in
  https://jira.spring.io/browse/SPR-8093

- Clean up nohttp allowlist.lines

Closes gh-28876
2022-09-14 17:00:11 +02:00
Sam Brannen 62a0ab3667 Polish contribution 2022-09-14 16:50:32 +02:00
Marc Wrobel 92a231cf91 Fix typos in Javadoc, reference docs, and code
Closes gh-28822
2022-09-14 16:45:34 +02:00
Sam Brannen 50dff77d01 Polish contribution 2022-09-14 16:08:01 +02:00
Marc Wrobel 0f479293b1 Replace use of the <tt> HTML tag in Javadoc
The <tt> HTML tag was used in HTML 4 to define teletype text. It is not
supported in HTML5, and its use is discouraged.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tt

Closes gh-28819
2022-09-14 15:56:16 +02:00
Johnny Lim 5f5d383eeb Fix Javadoc since tag for AbstractGenericWebContextLoader.createContext()
See gh-28983
Closes gh-29154
2022-09-14 15:53:18 +02:00
Sam Brannen 529481c44c Polish contribution
See gh-29150
2022-09-14 14:35:43 +02:00
Jens Dietrich 35d379f9d3 Add missing @Nullable in SettableListenableFuture
Closes gh-29150
2022-09-14 14:32:37 +02:00
Brian Clozel c871758a51 Upgrade to Reactor 2020.0.23
Closes gh-29129
2022-09-13 21:35:11 +02:00
Stephane Nicoll 0d2bfc926f Apply consistent ordering in hierarchical contexts
Previously, if `@Order` is specified on a `@Bean` method, and the
candidate bean is defined in a parent context, its order wasn't taken
into account when retrieving the bean from a child context.

This commit makes sure the metadata of a bean is taken into
consideration in all cases.

Closes gh-29105
2022-09-13 07:23:22 +02:00
rstoyanchev 4e97776969 Polishing contribution
Closes gh-28715
2022-09-12 11:47:55 +01:00
Napster d42f950a36 Pass headers to STOMP receipt callbacks
See gh-28715
2022-09-12 10:55:12 +01:00
rstoyanchev 4eabe29b9a Polishing contribution
Closes gh-28785
2022-09-12 10:52:53 +01:00
npriebe cd10171f98 Make WebSocketConnectionManager#isConnected public
See gh-28785
2022-09-12 09:54:57 +01:00
jbotuck 597c687da8 Fix indentation in ref docs for RestTemplate
Closes gh-29014
2022-09-12 09:51:33 +01:00
Stephane Nicoll 081d70123e Start building against Reactor 2020.0.23 snapshots
See gh-29129
2022-09-10 09:44:11 +02:00
Stephane Nicoll d9c2ccb4b3 Upgrade Ubuntu version in CI image
Closes gh-29106
2022-09-08 10:57:36 +02:00
Stephane Nicoll c503f356c7 Merge pull request #29104 from boahc077
* pr/29104:
  Restrict permissions for GitHub action

Closes gh-29104
2022-09-08 09:04:15 +02:00
Ashish Kurmi 7f9933fdb7 Restrict permissions for GitHub action
See gh-29104
2022-09-08 09:03:47 +02:00
Brian Clozel a425512025 Polish
See gh-29050
2022-09-07 15:02:10 +02:00
Kevin Yue 298c9a6f1b Redirect response wrapper should commit response
This commit ensures that when using `sendRedirect`, the response wrapper
behaves correctly with regards to the Servlet specification:

1. reset the response buffer to clear any partially written response
2. set the expected response HTTP headers
3. flush the buffer to commit the response

Closes gh-29050
2022-09-07 14:59:15 +02:00
Stephane Nicoll 8dcb2a75fa Merge pull request #29048 from 1993heqiang
* pr/29048:
  Fix typo in data-access section

Closes gh-29048
2022-09-05 07:23:56 +02:00
heqiang 111a9902ac Fix typo in data-access section
See gh-29048
2022-09-05 07:21:31 +02:00
Sam Brannen 0389fcca7e Fix sporadically failing SpEL test 2022-09-02 16:41:44 +02:00
junsu bb3ada4a67 Fix Kotlin Serialization converter registration logic
This commit fixes Kotlin Serialization converter
registration logic in RestTemplate,
AbstractMessageBrokerConfiguration and
AllEncompassingFormHttpMessageConverter classes
to be similar to the one in
WebMvcConfigurationSupport.

Closes gh-29008
2022-09-02 11:17:51 +02:00
Sam Brannen 6a68bd58f9 Introduce AnnotationUtils.isSynthesizedAnnotation(Annotation)
Since SynthesizedAnnotation will be deprecated (and potentially
completely removed) in Spring Framework 6.0, this commit introduces
AnnotationUtils.isSynthesizedAnnotation(Annotation) in 5.3.x to allow
people to migrate away from relying on SynthesizedAnnotation.

Closes gh-29054
2022-09-01 17:35:22 +02:00
Sam Brannen b1414bf15b Polishing 2022-09-01 17:23:04 +02:00
Arjen Poutsma f91943977c RenderingResponse must set status code on RedirectView
This commit makes sure that WebFlux's RenderingResponse sets the HTTP
status code when rendering a RedirectView.

Closes: gh-28839
2022-08-30 15:14:03 +02:00
Arjen Poutsma 4c0ece944a Fix race condition in PartGenerator
This commit fixes a race condition in PartGenerator, used by
DefaultPartHttpMessageReader. The condition can occur when a
completion signal comes in, and the state is changed to IdleFileState
at the same time.

Closes gh-28963
2022-08-30 12:11:22 +02:00
Sam Brannen 2c75eb8745 Support @Nested tests in MockServerContainerContextCustomizerFactory
Prior to this commit, MockServerContainerContextCustomizerFactory did
not find @WebAppConfiguration on an enclosing class and therefore
failed to create a MockServerContainerContextCustomizer for a @Nested
test class.

This commit addresses this by using TestContextAnnotationUtils to
determine if the test class is "annotated" with @WebAppConfiguration.

Closes gh-29037
2022-08-28 18:41:27 +02:00
Sam Brannen 711820ec70 Introduce createContext() factory method in AbstractWebGenericContextLoader
Prior to this commit it was possible to configure the
DefaultListableBeanFactory used by the GenericWebApplicationContext
created by AbstractWebGenericContextLoader, but it was not possible to
completely replace the bean factory.

This commit introduces a new createContext() factory method in
AbstractWebGenericContextLoader which indirectly allows subclasses to
supply a custom DefaultListableBeanFactory implementation to the
GenericWebApplicationContext.

See gh-25600
Closes gh-28983
2022-08-21 15:05:23 +02:00
Sam Brannen 69d87f16ee Reorganize internals of DefaultCacheAwareContextLoaderDelegate 2022-08-21 15:02:28 +02:00
Sam Brannen 38f94799f4 Use andExpectAll() in example in MockMvc Javadoc 2022-08-19 16:05:31 +02:00
Sam Brannen 4264d0becd Fix example in MockMvc Javadoc 2022-08-19 16:02:10 +02:00
Arjen Poutsma 7e7d6b9c3a Propagate Context in DataBufferUtils::write(Path)
This commit makes sure that the Reactor context is propagated in
DataBufferUtils::write(Path).

Closes gh-28933
See gh-27517
2022-08-16 11:21:12 +02:00
Stephane Nicoll dfc06eda7a Upgrade Java 8 version in CI image and .sdkmanrc 2022-08-11 13:31:36 +02:00
Stephane Nicoll f0aa6ebed6 Merge pull request #28949 from izeye
* pr/28949:
  Polish "Add missing TreeSet to CollectionFactory.createCollection()"
  Add missing TreeSet to CollectionFactory.createCollection()

Closes gh-28949
2022-08-11 10:43:56 +02:00
Stephane Nicoll 6806aaf162 Polish "Add missing TreeSet to CollectionFactory.createCollection()"
See gh-28949
2022-08-11 08:28:43 +02:00
Johnny Lim ccec75c98d Add missing TreeSet to CollectionFactory.createCollection()
See gh-28949
2022-08-11 08:22:11 +02:00
Stephane Nicoll 22029b4487 Merge pull request #28944 from wilkinsona
* pr/28944:
  Correct description of @RequestParam with WebFlux

Closes gh-28944
2022-08-09 15:32:17 +02:00
Andy Wilkinson d6b60046ce Correct description of @RequestParam with WebFlux
See gh-28944
2022-08-09 15:30:08 +02:00
Stephane Nicoll 6685e78c36 Deprecate NestedIOException
NestedIOException has been removed in Spring Framework 6 and this commit
marks it as deprecated in 5.x. Users that were relying on this exception
should use IOException directly.

Closes gh-28929
2022-08-05 10:04:47 +02:00
Chanhyeong Cho 8685b2f5bf Fix broken kdoc-api links in kotlin.adoc
Fixes gh-28908
2022-08-04 11:02:02 +02:00
Stephane Nicoll 4af225405c Upgrade Java 18 version in CI image 2022-08-04 10:02:49 +02:00
Stephane Nicoll 51e594ae81 Upgrade Java 17 version in CI image 2022-08-04 10:02:15 +02:00
Stephane Nicoll c2554b2b27 Upgrade Java 11 version in CI image 2022-08-04 10:01:49 +02:00
Stephane Nicoll 86a762b5ee Upgrade Java 8 version in CI image 2022-08-04 10:01:23 +02:00
Stephane Nicoll 211241befe Upgrade Ubuntu version in CI image 2022-08-04 10:00:30 +02:00
Brian Clozel 0caa2ac696 Customize connection in UrlResource getInputStream
Prior to this commit, the `AbstractFileResolvingResource` would
provide a default implementation for `customizeConnection` which only
sets the HTTP request method as "HEAD".
While this is consistent with its usage within that class (in
`exists()`, `contentLength()` or `lastModified()`), this is not opened
for general usage by sub-classes.

`UrlResource` is an example of that, where its `getInputStream()` method
does not call this customization method.

This not only prevents implementations from calling
`customizeConnection` in various cases, but it also misleads developers
as they might think that customizations will be applied automatically.

This commit ensures that `customizeConnection` is called in all relevant
places and that the configuration of the HTTP method is instead done in
each method as it is use case specific.

Fixes gh-28909
2022-08-03 23:13:52 +02:00
Stephane Nicoll 4eb8a5c082 Merge pull request #28914 from izeye
* pr/28914:
  Fix Javadoc since for new modules() and modulesToInstall()

Closes gh-28914
2022-08-02 16:11:04 +02:00
Johnny Lim d080b64907 Fix Javadoc since for new modules() and modulesToInstall()
See gh-28914
2022-08-02 16:10:47 +02:00
Stephane Nicoll 5ab55dfb64 Merge pull request #28183 from luvarqpp
* pr/28183:
  Polish "Improve documentation of Cacheable"
  Improve documentation of Cacheable

Closes gh-28183
2022-07-29 18:06:57 +02:00
Stephane Nicoll 04209def46 Polish "Improve documentation of Cacheable"
Apply the same improvements to CacheEvict and CachePut.

See gh-28183
2022-07-29 18:04:23 +02:00
luvarqpp 3a61930bd0 Improve documentation of Cacheable
See gh-28183
2022-07-29 17:57:15 +02:00
Stephane Nicoll 456c7889a3 Merge pull request #28488 from arend-von-reinersdorff
* pr/28488:
  Polish "Clarify docs on JNDI properties in Servlet environment"
  Clarify docs on JNDI properties in Servlet environment

Closes gh-28488
2022-07-29 17:13:42 +02:00
Stephane Nicoll 982d8ea84a Polish "Clarify docs on JNDI properties in Servlet environment"
See gh-28488
2022-07-29 17:09:55 +02:00
Arend v. Reinersdorff 67eb2bbf19 Clarify docs on JNDI properties in Servlet environment
See gh-28488
2022-07-29 17:05:58 +02:00
Stephane Nicoll a6596e2446 Merge pull request #28780 from vpavic
* pr/28780:
  Add missing nullability annotations to ResponseCookie

Closes gh-28780
2022-07-29 17:01:19 +02:00
Vedran Pavic 812b089f1d Add missing nullability annotations to ResponseCookie
See gh-28780
2022-07-29 16:54:37 +02:00
Rossen Stoyanchev 2172b99fee Polishing contribution
Closes gh-28836
2022-07-29 15:24:17 +03:00
floriankirmaier b6144e5682 Improve setting of WebSocket error status
See gh-28836
2022-07-29 15:07:15 +03:00
Rossen Stoyanchev 6e6f8637d1 Polishing contribution
Closes gh-28771
2022-07-29 14:45:42 +03:00
Johnny Lim 00f7f5ff0a Use MediaType.APPLICATION_FORM_URLENCODED_VALUE
See gh-28771
2022-07-29 14:40:45 +03:00
Arjen Poutsma 3d4a778b73 Fix KDoc API link 2022-07-29 11:08:57 +02:00
Stephane Nicoll 446c1add4f Merge pull request #28885 from edfeff
* pr/28885:
  Upgrade copyright year of changed file
  Fix typo in Javadoc of AbstractEncoder

Closes gh-28885
2022-07-29 09:31:42 +02:00
Stephane Nicoll aef4b0ec5a Upgrade copyright year of changed file
See gh-28885
2022-07-29 09:29:58 +02:00
wpp 675e0b94c1 Fix typo in Javadoc of AbstractEncoder
See gh-28885
2022-07-29 09:29:35 +02:00
Arjen Poutsma b8b54ee524 Ensure WebClient exceptions are serializable
Not all HttpHeaders implementations are serializable. This commit
ensures that WebClientRequestException and WebClientResponseException
are serializable, by copying any non-serializable HttpHeaders into a
new, serializable, instance.

Closes gh-28321
2022-07-28 14:09:11 +02:00
Arjen Poutsma 97ea8a6789 Copy HttpHeaders to ensure serializability
Not all HttpHeaders implementations are serializable. This commit
ensures that WebClientRequestException and WebClientResponseException
are serializable, by copying any non-serializable HttpHeaders into a
new, serializable, instance.

Closes gh-28321
2022-07-28 13:55:43 +02:00
Stephane Nicoll 95a400abfb Merge pull request #28867 from arvyy
* pr/28867:
  Add missing closing parenthesis

Closes gh-28867
2022-07-25 13:32:13 +02:00
arvyy 4383a673bb Add missing closing parenthesis
See gh-28867
2022-07-25 13:30:45 +02:00
Arjen Poutsma f7b94fc3e8 Updated sdkmanrc 2022-07-25 12:21:58 +02:00
Stephane Nicoll 93760d1211 Merge pull request #28853 from marcwrobel
* pr/28853:
  Polish "Deprecate SockJsServiceRegistration#setSupressCors"
  Deprecate SockJsServiceRegistration#setSupressCors

Closes gh-28853
2022-07-22 16:15:05 +02:00
Stephane Nicoll 421b5cb311 Polish "Deprecate SockJsServiceRegistration#setSupressCors"
See gh-28853
2022-07-22 16:07:47 +02:00
Marc Wrobel 1cc36e5be9 Deprecate SockJsServiceRegistration#setSupressCors
SockJsServiceRegistration#setSupressCors name contains a typo. It is
now deprecated in favor of a correctly spelled method, setSuppressCors.

See gh-28853
2022-07-22 16:06:54 +02:00
Stephane Nicoll f7c32d3a0b Merge pull request #28842 from adrianbob
* pr/28842:
  Reintroduce Javadoc links to Apache HttpClient 5.1 APIs

Closes gh-28842
2022-07-19 15:39:36 +02:00
Adrian Bob 9c0a2eeeb2 Reintroduce Javadoc links to Apache HttpClient 5.1 APIs
See gh-28842
2022-07-19 15:39:18 +02:00
Jupiter 7fa9f1c9cf Fix broken link to rsocket protocol page
Closes gh-28817
2022-07-19 10:14:46 +02:00
Arjen Poutsma 1e03b30d33 Use existing context path in DefaultServerRequestBuilder
Closes gh-28820
2022-07-14 15:10:31 +02:00
Spring Builds 7df149c8b8 Next development version (v5.3.23-SNAPSHOT) 2022-07-14 08:50:40 +00:00
rstoyanchev e50131d454 Add Consumer methods to configure Jackson modules
Closes gh-28633
2022-07-13 19:10:51 +01:00
rstoyanchev cdd4e8cd7f Improve regex support for URL path matching
Closes gh-28815
2022-07-13 18:43:51 +01:00
Juergen Hoeller 02b7ddbc70 Upgrade to Log4J 2.18, H2 2.1.214, OpenPDF 1.3.29, XStream 1.4.19, HtmlUnit 2.63, Jetty Reactive HttpClient 1.1.12 2022-07-13 16:48:02 +02:00
Juergen Hoeller 8e5c4903d4 Avoid synchronization in AbstractAspectJAdvice#calculateArgumentBindings
Aligned with the early calculateArgumentBindings call in ReflectiveAspectJAdvisorFactory.

Closes gh-26377
2022-07-13 16:47:35 +02:00
Marc Wrobel bd3499671c Fix typos in test code
This commit fixes typos in test class names, test method names, and
test variable names.

Closes gh-28807
2022-07-13 16:24:11 +02:00
Sam Brannen 2e4d7e4ef9 Polishing 2022-07-13 16:13:09 +02:00
Marc Wrobel c6be3b33c9 Fix and improve Javadoc in spring-aop
Closes gh-28803
2022-07-13 16:13:02 +02:00
Marc Wrobel c112bb0ae1 Fix and improve Javadoc in spring-beans
See gh-28803
2022-07-13 16:12:51 +02:00
Marc Wrobel 165fba868c Fix typos in reference docs
Closes gh-28805
2022-07-13 15:12:31 +02:00
Marc Wrobel 2ca64ad88a Fix minor typos in project README
See gh-28805
2022-07-13 15:12:21 +02:00
Sam Brannen ea27206a32 Polishing 2022-07-13 14:45:31 +02:00
Marc Wrobel c48c5e7691 Fix and improve Javadoc in spring-context
Closes gh-28802
2022-07-13 14:45:23 +02:00
Marc Wrobel bc15f839cd Fix and improve Javadoc in spring-core
See gh-28802
2022-07-13 14:45:13 +02:00
Sam Brannen 46db372951 Polishing 2022-07-13 14:01:47 +02:00
Marc Wrobel 91258271e4 Fix and improve Javadoc in spring-expression
Closes gh-28800
2022-07-13 14:01:41 +02:00
Marc Wrobel e76fbcb290 Fix and improve Javadoc in spring-jms
See gh-28800
2022-07-13 14:01:37 +02:00
Marc Wrobel 82ca27e46f Fix and improve Javadoc in spring-messaging
See gh-28800
2022-07-13 14:01:29 +02:00
Marc Wrobel bca104798b Fix and improve Javadoc in spring-jdbc
Closes gh-28796
2022-07-13 13:42:48 +02:00
Marc Wrobel b30eb6837c Fix and improve Javadoc in spring-oxm
See gh-28796
2022-07-13 13:42:42 +02:00
Marc Wrobel ac06d1dfa9 Fix and improve Javadoc in spring-orm
See gh-28796
2022-07-13 13:42:33 +02:00
Marc Wrobel cfb39acc97 Fix and improve Javadoc in spring-r2dbc
See gh-28796
2022-07-13 13:42:16 +02:00
Sam Brannen 222dbf8377 Update copyright date 2022-07-13 13:22:40 +02:00
kacperkrzyzak 10838a636f Correctly identify MaxUploadSizeExceededException in StandardMultipartHttpServletRequest
This commit correctly identifies MaxUploadSizeExceededException in
StandardMultipartHttpServletRequest by converting keywords in the
exception message to lowercase before checking for their presence, for
compatibility with Jetty 9.4.x.

Closes gh-28759
2022-07-13 13:17:53 +02:00
Juergen Hoeller 3c3ae32f07 Upgrade to Netty 4.1.79, Jetty 9.4.48, Undertow 2.2.18, Checkstyle 10.3.1 2022-07-13 11:11:17 +02:00
Juergen Hoeller a3e46a2db7 ResolvableType.forInstance returns NONE for null instance
Closes gh-28776
2022-07-13 11:10:35 +02:00
Juergen Hoeller de1b938e2e Improve diagnostics for CGLIB ClassLoader mismatch with --add-opens hint
Closes gh-28747
2022-07-13 11:10:00 +02:00
Juergen Hoeller d72aeac319 Create well-known non-interface types without using reflection
Closes gh-28718
2022-07-13 11:09:43 +02:00
Juergen Hoeller 5247eeba84 Support LocalDate/Time for SQL type mappings
Closes gh-28778
2022-07-13 11:09:30 +02:00
Juergen Hoeller ae70e3c81c Apply read-only enforcement after R2DBC transaction begin
Includes prepareTransactionalConnection variant aligned with JDBC DataSourceTransactionManager.

Closes gh-28610
2022-07-13 11:09:17 +02:00
Sébastien Deleuze c942c8d2cf Fix expectations in MockMvc Kotlin documentation
Closes gh-28301
2022-07-13 10:06:41 +02:00
Sébastien Deleuze 1201af20e4 Improve consistency of Kotlin injection code samples
Closes gh-28596
2022-07-13 09:42:47 +02:00
Sébastien Deleuze d1df4d3739 Fix Kotlin code snippets language
Closes gh-28810
2022-07-13 09:21:02 +02:00
Sébastien Deleuze 1ef8800c6c Fix Kotlin example for custom @Production
Closes gh-28680
2022-07-13 09:13:47 +02:00
Sébastien Deleuze 4d7e4e0c58 Fix a typo
See gh-28630
2022-07-12 18:54:01 +02:00
Stephane Nicoll c7067269b3 Upgrade to Reactor 2020.0.21
Closes gh-28765
2022-07-12 14:31:43 +02:00
Sam Brannen 3af6a22b9f Temporarily disable Javadoc links to Apache HttpClient 5.1 APIs 2022-07-12 13:26:07 +02:00
Sam Brannen 31a9694fc8 Improve Javadoc for ContextCache#clearStatistics()
See gh-28795
2022-07-12 13:04:34 +02:00
Marc Wrobel 92b8e99cbc Fix and improve Javadoc in spring-test
Closes gh-28795
2022-07-12 12:55:59 +02:00
Marc Wrobel 3b68e97710 Fix and improve Javadoc in spring-tx
Closes gh-28794
2022-07-12 12:36:49 +02:00
Marc Wrobel 6f494ef438 Fix and improve Javadoc in spring-web
Closes gh-28791
2022-07-12 12:08:12 +02:00
Sam Brannen 19704805fd Polish contribution
See gh-28790
2022-07-12 11:56:01 +02:00
Marc Wrobel 31c6965c7f Fix and improve Javadoc in spring-webflux
Closes gh-28790
2022-07-12 11:48:58 +02:00
Sam Brannen 5b1a84e395 Polish contribution
See gh-28789
2022-07-12 10:39:11 +02:00
Marc Wrobel 6985fa8057 Fix and improve Javadoc in spring-webmvc
Closes gh-28789
2022-07-12 10:39:03 +02:00
Marc Wrobel 03f0c57704 Fix and improve Javadoc in spring-websocket
Closes gh-28788
2022-07-11 21:30:32 +02:00
Sam Brannen d274e893a6 Remove superfluous static declaration for enum, annotation, & interface 2022-07-09 16:16:13 +02:00
Arjen Poutsma aa8b06b622 Delete file on multipart cancel
This commit makes sure that the temporary file used for multipart
storage is deleted when the source stream is malformed or cancelled.

Closes gh-28740
2022-07-08 16:36:01 +02:00
Sam Brannen 323dbb912e Move convention-based attribute override tests to @Nested class 2022-07-06 13:19:41 +02:00
rstoyanchev 63d7e81a48 Switch to Reactor 2020-0.21 snapshots
See gh-28765
2022-07-06 11:30:44 +01:00
Sam Brannen 07960d4918 Polishing 2022-07-06 11:44:15 +02:00
Sam Brannen 07cfcbc3a9 Move convention-based attribute override tests to @Nested class 2022-07-06 11:42:39 +02:00
Sam Brannen 2af27d899f Trim string input in Converters where whitespace is irrelevant
Closes gh-28756
2022-07-05 13:53:00 +02:00
Sam Brannen 0621a8eff1 Fix concurrency issues in FreeMarkerMacroTests
Prior to this commit, tests in these two classes intermittently failed
with errors similar to the following, due to concurrent modification
of shared files.

expected:
  "<input type="text" id="name" name="name" value="Darren"     >"
 but was:
  "<input type="text" id="name" name="name" value="Darren"     >

  "hidden"/>"

This commit fixes this by creating a new temporary folder for each test
method invocation.
2022-07-05 13:17:50 +02:00
Sam Brannen 7ac646bc96 Upgrade to TestNG Engine 1.0.4 2022-07-05 12:43:05 +02:00
Sam Brannen 2c3243c93c Trim string input in PropertyEditors where whitespace is irrelevant
Closes gh-28755
2022-07-04 19:24:58 +02:00
Sam Brannen 2bf5f7a6b3 Introduce lenient parsing in DataSize regarding whitespace
Prior to this commit, a DataSize input string could not be parsed if it
contained any whitespace.

With this commit, a DataSize input string can contain leading, trailing,
or 'in between' whitespace. For example, the following will be parsed
to the same DataSize value.

- "1024B"
- "1024 B"
- " 1024B "
- " 1024 B "

Closes gh-28643
2022-07-04 19:24:58 +02:00
Sam Brannen bf39492c34 Introduce StringUtils.trimAllWhitespace(CharSequence)
Closes gh-28757
2022-07-04 19:24:45 +02:00
rstoyanchev 007bdede46 Add missing check to avoid re-initialization
Noticed during review of #28736 that a check protecting against
re-initialization was accidentally removed in commit
3d6e38bb43.
2022-07-04 16:17:57 +01:00
rstoyanchev 22cc6c5918 Polishing contribution
Closes gh-28736
2022-07-04 16:12:57 +01:00
CodeInDreams 461ba53b39 Qualify channelExecutor and taskScheduler in WebSocket config
See gh-28736
2022-07-04 15:51:40 +01:00
Sam Brannen d1d6eb095e Fix GenericApplicationContextTests on Microsoft Windows (round 2)
The previous change to the tests resulted in a failure on Windows when
using the DefaultResourceLoader by expecting an exception when no
exception is thrown.

This commit narrows the scope of the if-clause to expect an exception
only when using the FileSystemResourceLoader on Windows.

See gh-28703, gh-28746
2022-07-03 17:59:37 +02:00
Sam Brannen f732fab820 Delete unused imports and dead code in CGLIB fork 2022-07-03 17:30:30 +02:00
Sam Brannen fda3f8201a Switch warning level for forbidden reference to INFO in Eclipse IDE 2022-07-03 17:23:55 +02:00
Sam Brannen e608b36713 Improve GenericApplicationContextTests.getResource*() tests
This commit updates the tests so that they test something meaningful on
MS Windows as well as on Linux/Mac.

See gh-28703, gh-28746
2022-07-03 14:36:41 +02:00
jason 59180e76a7 Fix GenericApplicationContextTests on Microsoft Windows
The tests introduced in commit 9868c28c73 pass on Mac OS and Linux but
fail on Microsoft Windows.

This commit updates the tests so that they pass on MS Windows as well.

See gh-28703
Closes gh-28746
2022-07-03 14:35:07 +02:00
Sam Brannen c5987d7c37 Fix typo in test 2022-07-02 17:09:07 +02:00
Sam Brannen 5650e20edd Polishing 2022-07-01 10:42:23 +02:00
Johnny Lim 2885177f5b Add @since tag for new CannotGetJdbcConnectionException constructor
See gh-28669
Closes gh-28738
2022-07-01 10:39:35 +02:00
rstoyanchev 058ce36402 Improve ExtendedWebExchangeDataBinder implementation
Close gh-28646
2022-07-01 03:23:32 +01:00
Vikey Chen 2afe560e41 Replace forEach with putAll
See gh-28646
2022-07-01 03:01:12 +01:00
rstoyanchev b95362a3fd Avoid request params access for form data in logRequest
Close gh-28587
2022-07-01 02:55:16 +01:00
Sam Brannen 9ea45697ac Support cookie comments in MockHttpServletResponse and MockCookie
Prior to this commit, if a cookie was added to MockHttpServletResponse,
the comment attribute was not included in the generated Set-Cookie
header. In addition, MockCookie.parse(String) did not support the
Comment attribute.

This commit addresses both of these issues.

Closes gh-28730
2022-06-30 16:51:43 +02:00
Johnny Lim fe2b8580a0 Upgrade to Gradle Enterprise Conventions 0.0.10 2022-06-30 14:59:55 +02:00
Sam Brannen 622fc3edf7 Fix merged annotation attributes regression
Commit d6768ccc18 introduced a regression in the support for merging
annotation attributes in a multi-level annotation hierarchy.

This commit addresses that issue by ensuring that a merged annotation
is once again synthesized if a meta-annotation in the annotation
hierarchy declares attributes that override attributes in the target
annotation.

Closes gh-28716
2022-06-28 14:22:53 +02:00
Sam Brannen 9868c28c73 Honor ProtocolResolvers in GenericApplicationContext
When the ProtocolResolver SPI was introduced in Spring Framework 4.3,
support for protocol resolvers was added in DefaultResourceLoader's
getResource() implementation; however, GenericApplicationContext's
overridden getResource() implementation was not updated accordingly.

Prior to this commit, if a GenericApplicationContext was configured
with a custom ResourceLoader, registered protocol resolvers were
ignored.

This commit ensures that protocol resolvers are honored in
GenericApplicationContext even if a custom ResourceLoader is used.

Closes gh-28703
2022-06-27 18:00:29 +02:00
Sam Brannen a970516080 Polish GenericApplicationContextTests 2022-06-27 17:05:02 +02:00
Sam Brannen 0c9def89de Ignore build artifacts from the main branch for nohttp 2022-06-27 15:05:05 +02:00
Sam Brannen 8892a05868 Ignore /spring-core/graalvm/build artifacts from the main branch
This commit eases switching between the `main` and `5.3.x` branches.
2022-06-27 14:43:06 +02:00
Sam Brannen d6768ccc18 Ensure meta-annotations are not unnecessarily synthesized
Prior to this commit, meta-annotations were unnecessarily synthesized
when attempting to synthesize a MergedAnnotation retrieved via the
MergedAnnotations.from(AnnotatedElement, ...).get(<annotationType>) API.

This is a regression in our merged annotation support that was
introduced when the MergedAnnotations API replaced our previous support.

This commit fixes this by revising the logic in TypeMappedAnnotation's
createSynthesizedAnnotation() method so that a meta-annotation is
returned unmodified if it is not synthesizable.

This commit also updates BootstrapUtilsTests, since @BootstrapWith
should never have been synthesized, and Class#getCanonicalName() is
only used in the toString() implementation of an annotation synthesized
by Spring or normal annotations on Java 19+ (see
https://bugs.openjdk.org/browse/JDK-8281462).

Closes gh-28704
2022-06-25 20:02:04 +02:00
Sam Brannen faf20b7a5a Polish MergedAnnotations Javadoc and internals 2022-06-25 19:50:03 +02:00
Sam Brannen 661996471e Polishing 2022-06-25 19:24:51 +02:00
Stephane Nicoll 5639ff0939 Merge pull request #28669 from kevin0x90
* pr/28669:
  Polish "Fix DataSourceUtils inconsistent exception handling"
  Fix DataSourceUtils inconsistent exception handling

Closes gh-28669
2022-06-23 09:04:40 +02:00
Stephane Nicoll e98b602d4f Polish "Fix DataSourceUtils inconsistent exception handling"
See gh-28669
2022-06-23 09:01:39 +02:00
Kevin Schönfeld edfe5d2f18 Fix DataSourceUtils inconsistent exception handling
Align IllegalStateException with SQLException handling and propagate
the original exception.

See gh-28669

Co-authored-by: Christoph Mies <chr.mi@web.de>
2022-06-23 09:01:39 +02:00
Sam Brannen 26df4580b3 Revise internals of LoggingCacheErrorHandler
Since LoggingCacheErrorHandler was only recently introduced in 5.3.16,
we have decided to completely revise its internals (protected API) in
5.3.x while retaining the current public API.

Specifically, this commit:

- introduces protected getLogger() and isLogStackTraces() methods to
  improve extensibility

- revises logCacheError() to accept a Supplier<String> for lazy
  resolution of error messages

Closes gh-28672
See gh-28670, gh-28648
2022-06-21 16:13:55 +02:00
Vedran Pavic 57208bf47a Simplify LoggingCacheErrorHandlerTests
See gh-28648
2022-06-21 14:40:09 +02:00
Sam Brannen 8b34558284 Polish LoggingCacheErrorHandler 2022-06-21 14:07:39 +02:00
Vedran Pavic dbe8f200a9 Simplify creation of LoggingCacheErrorHandler with logged stacktrace
At present, creating a LoggingCacheErrorHandler that logs stack traces
also requires supplying the logger to be used. This might be
inconvenient for some users, as it requires usage of the Commons
Logging API.

This commit simplifies creation of such as LoggingCacheErrorHandler
instance by adding a constructor that only accepts a boolean flag
indicating whether to log stack traces.

Closes gh-28670
2022-06-21 13:50:10 +02:00
Sam Brannen ea4d9a20ac Upgrade to Hamcrest 2.2 2022-06-21 13:48:02 +02:00
Sam Brannen e19e9757d4 Polishing 2022-06-20 15:19:02 +02:00
Jerome Prinet 2473e956ff Update Gradle Enterprise plugin
Closes gh-28661
2022-06-20 11:40:43 +02:00
Sébastien Deleuze 854307d8d8 Document that Kotlin inline classes are not supported
Closes gh-28642
2022-06-17 12:34:58 +02:00
Sébastien Deleuze 3401359bdf Refine @Required Kotlin documentation
Refine @Required Kotlin documentation to use
annotation use site targets.

Closes gh-28630
2022-06-17 12:25:52 +02:00
Sébastien Deleuze f1c00dd8a6 Fix a typo in ResponseEntity documentation
Closes gh-28647
2022-06-17 12:15:22 +02:00
Sam Brannen bdf91ac435 Set default encoding for Eclipse projects to UTF-8
This change aligns with Java 18 support in recent versions of Eclipse.
2022-06-16 16:13:35 +02:00
Lars Grefer 181023c0c3 Update to Bouncycastle 1.71
Closes gh-28636
2022-06-16 16:03:11 +02:00
Sam Brannen fb1fa073a6 Polishing 2022-06-15 15:07:58 +02:00
Sam Brannen e9806a96dc Polish contribution and introduce test
See gh-28631
2022-06-15 15:07:58 +02:00
Johnny Lim 9b93508374 Add MockMvcRequestBuilders.multipart(HttpMethod, String, Object...)
See gh-28545
Closes gh-28631
2022-06-15 14:09:59 +02:00
Sam Brannen 8b4750e705 Fix Kotlin example for @ComponentScan basePackages attribute
Closes gh-28628
2022-06-15 11:27:39 +02:00
Spring Builds 2e033339d1 Next development version (v5.3.22-SNAPSHOT) 2022-06-15 08:17:52 +00:00
Stephane Nicoll c75da7ba10 Upgrade to Reactor 2020.0.20
Closes gh-28612
2022-06-14 19:27:03 +02:00
Sam Brannen eeac150030 Polish contribution
See gh-28616
2022-06-14 16:42:51 +02:00
Fabian Gonzalez 0ce9516aef Avoid eager instantiation of non-singleton FactoryBean in getBeanNamesForType
Closes gh-28616
2022-06-14 16:42:31 +02:00
Sam Brannen e47cc44947 Polish DefaultListableBeanFactoryTests 2022-06-14 16:38:11 +02:00
Juergen Hoeller 57db73dcb8 Upgrade to Tomcat 9.0.64, Jackson 2.12.7, Apache Johnzon 1.2.18, OpenPDF 1.3.28, H2 2.1.212, Mockito 4.6.1, HtmlUnit 2.62, Checkstyle 10.3 2022-06-14 15:10:17 +02:00
Juergen Hoeller d7be1e0dab Polishing 2022-06-14 15:09:39 +02:00
Juergen Hoeller 30c873b4b5 Move NestedServletExceptionTests to spring-web module
See gh-25162
2022-06-14 15:09:21 +02:00
Juergen Hoeller e72b0a04cd Document limitations for MessageProducer/Consumer caching with WebLogic JMS
Closes gh-28500
2022-06-14 15:09:10 +02:00
Juergen Hoeller f8b41c1ad2 Consistent support for setContextClass in CGLIB beans package
Closes gh-28530
2022-06-14 15:08:44 +02:00
rstoyanchev 8c777111fa Revise commit #52d068 with corrected test
Update test detecting RouterFunction beans in parent contexts to use
different bean names and avoid shadowing. Changed the fix accordingly
given that BeanProvider does detect beans in parent contexts.

See gh-28595
2022-06-14 10:07:56 +01:00
rstoyanchev d28d603081 Polishing
See gh-28595
2022-06-14 09:35:17 +01:00
rstoyanchev 52d0681ca1 WebMvc respects RouterFunction beans ordering
Closes gh-28595
2022-06-14 09:20:19 +01:00
Sam Brannen 97854d9fec Refactor ObjectToObjectConverter to use Executable instead of Member 2022-06-13 18:01:54 +02:00
Sam Brannen 73f3860bb7 Polish Javadoc for ObjectToObjectConverter 2022-06-13 18:01:05 +02:00
Sam Brannen 452f1b877c Consider return type of static methods in ObjectToObjectConverter
Prior to this commit, ObjectToObjectConverter considered the return
type of non-static `to[targetType.simpleName]()` methods but did not
consider the return type of static `valueOf(sourceType)`,
`of(sourceType)`, and `from(sourceType)` methods.

This led to scenarios in which `canConvert()` returned `true`, but a
subsequent `convert()` invocation resulted in a
ConverterNotFoundException, which violates the contract of the
converter.

This commit addresses this issue by taking into account the return type
of a static valueOf/of/from factory method when determining if the
ObjectToObjectConverter supports a particular conversion. Whereas the
existing check in `determineToMethod()` ensures that the method return
type is assignable to the `targetType`, the new check in
`determineFactoryMethod()` leniently ensures that the method return
type and `targetType` are "related" (i.e., reside in the same type
hierarchy).

Closes gh-28609
2022-06-13 17:20:18 +02:00
Arjen Poutsma c278d8c656 Do not ignore charset in Jaxb2XmlDecoder
This commit makes sure that the charset, if defined in the mimetype, is
used when decoding XML to JAXB2 objects.

Closes gh-28599
2022-06-13 13:47:31 +02:00
Stephane Nicoll e3b288716d Upgrade to Reactor 2020.0.20
Closes gh-28612
2022-06-13 11:39:15 +02:00
Arjen Poutsma 27738cc20f Fix code samples for nested router functions
Closes gh-28603
2022-06-10 13:36:33 +02:00
Sam Brannen babff8e635 Fix Kotlin example for dependency injection with static factory method
Closes gh-28589
2022-06-09 13:16:19 +02:00
Sam Brannen 290cc73d3d Fix Kotlin example for @Required
Since @Required can only be declared on a method, this commit moves the
@Required declaration from the field to the "set" method.

Closes gh-28590
2022-06-09 13:13:43 +02:00
Stephane Nicoll 8a30bc2993 Upgrade Java 18 version in CI image 2022-06-09 08:14:54 +02:00
Stephane Nicoll aa8be28a01 Upgrade Java 17 version in CI image 2022-06-09 08:14:30 +02:00
Stephane Nicoll f43b28e7ba Upgrade Java 11 version in CI image 2022-06-09 08:14:05 +02:00
Stephane Nicoll 1476867ee7 Upgrade Java 18 version in CI image 2022-06-09 08:13:36 +02:00
Stephane Nicoll 4d9dc61f5d Polish 2022-06-09 08:13:12 +02:00
Stephane Nicoll 7eebc48a6e Upgrade Ubuntu version in CI image 2022-06-09 08:11:36 +02:00
Sam Brannen 8478e8e70a Polish contribution
This commit:

- fixes Checkstyle violations
- improves Javadoc
- adds missing @since tags
- renames getCurrentQueueSize() to getQueueSize()
- avoids NullPointerExceptions in getQueueSize()
- introduces tests for queue size and queue capacity

Closes gh-28583
2022-06-08 16:39:10 +02:00
Rémy e386bdb82c Expose ThreadPoolTaskExecutor queue size and capacity for metrics
We use Grafana to monitor our app via Spring's JMX exporter, and we
think it could be interesting to have at least the current queue size
for this purpose since the queue size directly affects the app memory
load. Having the queue capacity seems also interesting to set up
triggers whose values are calculated based on the maximum capacity of
the queue.

This commit introduces new getCurrentQueueSize() and getQueueCapacity()
methods in ThreadPoolTaskExecutor.

See gh-28583
2022-06-08 16:39:00 +02:00
Arjen Poutsma 4912c3c455 Updated sdkmanrc 2022-06-08 12:13:21 +02:00
rstoyanchev 8fcc7ab9d1 CompositeLog respects log level changes at runtime
Closes gh-28477
2022-06-08 10:07:52 +01:00
rstoyanchev 7c47b470ff MockMvc allows HttpMethod input for multipart request
Closes gh-28545
2022-06-08 10:07:52 +01:00
Sam Brannen 479ef3f3fd Update documentation regarding nested test class support
Closes gh-28579
2022-06-08 09:52:42 +02:00
Sam Brannen be1b7da12f Add entries for "Sam Brannen" to .mailmap 2022-06-07 14:27:42 +02:00
Phillip Webb 89360b18f4 Update '.mailmap` to consistently use @vmware.com emails
(cherry picked from commit 83063a7269)
2022-06-07 14:14:10 +02:00
Stephane Nicoll 209fe5f452 Merge pull request #28572 from gorisanson
* pr/28572:
  Polish contribution
  Update reference docs to use PropertySourcesPlaceholderConfigurer

Closes gh-28572
2022-06-07 08:30:52 +02:00
Stephane Nicoll e18a118f8b Polish contribution
See gh-28572
2022-06-07 08:29:28 +02:00
Lee, Kyutae 77aac7768d Update reference docs to use PropertySourcesPlaceholderConfigurer
See gh-28572
2022-06-07 08:22:53 +02:00
Sam Brannen e2767371b5 Lazily initialize DataSize.PATTERN
To avoid unnecessary eager initialization of DataSize.PATTERN, this
commit initializes it lazily in the first invocation of DataSize.parse
by moving PATTERN to a private static nested class.

Closes gh-28560
2022-06-03 13:30:45 +02:00
Sam Brannen aab9da0366 Polish LocaleResolver support 2022-06-03 13:10:55 +02:00
Sam Brannen cda1e5507c Polishing 2022-06-01 16:28:05 +02:00
Balázs Póka 1d5ffaf30a Always construct new exception on error in DefaultWebClient
Always construct new exception on error, otherwise memory leak may
occur due to repeated use of singleton exception.

Closes gh-28550
2022-06-01 16:07:41 +02:00
Arjen Poutsma c55606ed08 Recognize Kotlin coroutines in isAsyncVoidReturnType
This commit makes sure that Kotlin coroutines are correctly identified
by InvocableHandlerMethod::isAsyncVoidReturnType.

Closes gh-26829
2022-06-01 15:13:30 +02:00
Sam Brannen aa8802a81d Avoid new AssertJ deprecations 2022-05-31 16:13:31 +02:00
Sam Brannen 1beb7068f6 Use new AssertJ exception assertions 2022-05-31 14:08:28 +02:00
Sam Brannen 9d324e59a0 Upgrade to AssertJ 3.23.0 2022-05-31 12:55:43 +02:00
Sam Brannen 8547f8601d Polish LocaleResolver tests 2022-05-31 11:55:30 +02:00
Stephane Nicoll 40cb81470b Merge pull request #28542 from eltociear
* pr/28542:
  Fix typo in webflux.adoc

Closes gh-28542
2022-05-31 10:01:30 +02:00
Ikko Ashimine 6e3b3c5419 Fix typo in webflux.adoc
See gh-28542
2022-05-31 10:01:13 +02:00
Sam Brannen a221835558 Throw IllegalStateException for invalid port in HierarchicalUriComponents
Prior to this commit, getPort() in HierarchicalUriComponents threw a
NumberFormatException for an invalid port supplied as a String, which
was inconsistent with exception handling elsewhere in the class as well
as within the same method.

This commit introduces a try-catch block in getPort() to consistently
throw IllegalStateExceptions for ports that cannot be parsed.

Closes gh-28521
2022-05-25 11:29:12 +02:00
Sam Brannen aa06a09dee Polishing 2022-05-25 11:29:12 +02:00
hsteinmueller bde0931e51 Fix Javadoc for DatabaseClient
The documentation for DatabaseClient had misplaced double quotes in the
example on how to map a select statement to a row.

Closes gh-28520
2022-05-24 17:15:44 +02:00
Sam Brannen 7b95c928d1 Fix Javadoc for ResourcePatternResolver 2022-05-23 20:32:01 +02:00
Sam Brannen 53f88d455f Fix Javadoc for AbstractFileResolvingResource.isFile(URI) 2022-05-23 20:32:01 +02:00
Sam Brannen 53a506f6bb Polishing 2022-05-23 20:22:37 +02:00
rstoyanchev f95bf96ec9 Correct path encoding/decoding in PathResourceResolver
Decoding is required for non-UrlResource when the HandlerMapping is
not expected to decode the path. Encoding is the opposite.

This commit ensures correct determination of whether the HandlerMapping
is expected to have decoded the path or not that in turn depends on
whether PathPattern or PathMatcher is in use.

Closes gh-27791
2022-05-23 11:03:42 +01:00
rstoyanchev 66a5742df3 Polishing 2022-05-23 10:07:03 +01:00
Sam Brannen 59c7bb1f86 Use Arrays.toString instead of Arrays.asList when generating Strings 2022-05-17 15:36:31 +02:00
Sam Brannen a1c3efbb5f Polish ManagedList[Tests] and ManagedSet[Tests] 2022-05-17 15:36:31 +02:00
Sam Brannen 6efe3aee34 Polishing 2022-05-16 11:20:20 +02:00
Sam Brannen f2fe7f335c Improve nullReturningBeanPostProcessor() test
See gh-28459
2022-05-14 18:30:39 +02:00
Sam Brannen 48c797e429 Fix Kotlin example for static factory method
Closes gh-28399
2022-05-11 17:33:31 +02:00
Sam Brannen be782a2197 Polish ref docs regarding the BeanFactory API
See gh-28403
2022-05-11 17:16:40 +02:00
Sam Brannen 8098e45bad Sync gradle.properties between 5.3.x and main 2022-05-11 16:30:44 +02:00
Sam Brannen 06679a5583 Fix tests in DispatcherServletTests
See gh-28424
2022-05-11 16:00:26 +02:00
Sam Brannen 745eb1a881 Polish DispatcherServletTests 2022-05-11 15:59:47 +02:00
Spring Builds 10c55ff912 Next development version (v5.3.21-SNAPSHOT) 2022-05-11 07:08:24 +00:00
Juergen Hoeller 83186b689f Refine CachedIntrospectionResults property introspection
Closes gh-28445
2022-05-11 08:32:06 +02:00
rstoyanchev dc2947c52d Ignore invalid connect frame
Closes gh-28443
2022-05-11 07:22:22 +01:00
Arjen Poutsma e4ec376075 Disabling Undertow server in CoroutinesIntegrationTests 2022-05-10 15:55:00 +02:00
Juergen Hoeller c81e11d537 Polishing 2022-05-10 13:07:00 +02:00
Juergen Hoeller de6180b093 Upgrade to Reactor 2020.0.19
Includes Netty 4.1.77 and RxJava 3.1.4.

Closes gh-28437
2022-05-10 13:05:56 +02:00
Sam Brannen 1c10cdd1e8 Update copyright dates
See gh-28433
2022-05-10 11:33:32 +02:00
evgeny.bovykin 941b92cbed Make inner classes static when feasible
A static nested class does not keep an implicit reference to its
enclosing instance.

This prevents a common cause of memory leaks and uses less memory per
instance of the class.

Closes gh-28433
2022-05-10 11:32:37 +02:00
Sam Brannen e26d8839b3 Stop referring to features as Java 6/7 features where unnecessary 2022-05-09 19:09:06 +02:00
Sam Brannen a1c7380398 Add test for value attribute in @ModelAttribute in WebFlux
This complements the previous commit which tested only the `name`
attribute.

See gh-28423
2022-05-09 15:22:22 +02:00
Sam Brannen 7dd622bdb2 Support name attribute in @ModelAttribute in WebFlux
Prior to this commit, the `name` attribute in @ModelAttribute was not
supported when using WebFlux. This is because MethodParameter was used
instead of SynthesizingMethodParameter when retrieving the
@ModelAttribute annotation. In other words, @AliasFor was not honored
because the annotation was not synthesized. Consequently, only the
`value` attribute was supported in WebFlux when specifying a custom name
via @ModelAttribute.

This commit fixes this by using SynthesizingMethodParameter to retrieve
the @ModelAttribute annotation.

Closes gh-28423
2022-05-07 17:16:26 +02:00
Sam Brannen 64c96c579d Polish contribution
See gh-28422
2022-05-07 16:18:47 +02:00
Carlos Bouzón García 39e3876301 Fix BindingResult error when ModelAttribute has custom name in WebFlux
Closes gh-28422
2022-05-07 16:18:04 +02:00
Juergen Hoeller f771603789 Polishing 2022-05-05 18:04:54 +02:00
Juergen Hoeller e441832e99 Accept WritableResource as required dependency type as well
Closes gh-15284
2022-05-05 18:04:13 +02:00
Juergen Hoeller f963fc5f98 Check that nullable annotations are from org.springframework.lang
Closes gh-28410
2022-05-05 18:02:27 +02:00
Juergen Hoeller b55eee1b0d Upgrade to ASM 9.3
Closes gh-28390
2022-05-05 18:01:53 +02:00
Juergen Hoeller 28742171fd Upgrade to Netty 4.1.76, Mockito 4.5.1, HtmlUnit 2.61 2022-05-05 18:01:31 +02:00
Lee, Kyutae 7a75b94556 Fix typo in reference docs regarding RequestMappingHandlerAdapter
Closes gh-28370
2022-05-05 16:31:40 +02:00
Sam Brannen ab71ff93bb Polish package-info for org.springframework.util
See gh-28411
2022-05-05 16:22:52 +02:00
neals cf30327740 Remove Log4J configurer from package-info.java in spring-core
Closes gh-28411
2022-05-05 16:16:49 +02:00
neals e22a038725 Remove Log4J initialization from package-info.java
Closes gh-28420
2022-05-05 16:10:59 +02:00
Brian Clozel 7aedb9ee33 Build CI image using oci-build-task resource 2022-05-03 15:50:29 +02:00
Brian Clozel 5b1719cd77 Upgrade CI to concourse-release-scripts 0.3.4 2022-05-03 15:09:23 +02:00
Brian Clozel c056b81753 Upgrade JDK and Ubuntu versions in CI image 2022-05-03 15:08:14 +02:00
Brian Clozel dbdd67ec62 Remove outdated docker-image resource from CI
The docker-image resource is now replaced by the registry-image
resource.
2022-05-03 15:05:58 +02:00
Sam Brannen 4fcfa5b991 Update and simplify ArrayConstructorTests 2022-05-03 14:27:48 +02:00
Sam Brannen ed06a6de26 Convert SimpleFormController example to @Controller in reference manual
This change is necessary since the SimpleFormController class no longer
exists.
2022-05-03 12:03:04 +02:00
Sam Brannen afa799b4f0 Suppress warning in test 2022-05-03 11:46:47 +02:00
rstoyanchev f0d149b330 Polishing contribution
Closes gh-27830
2022-04-28 11:26:50 +01:00
binchoo caaf83b8e6 Add tests for binding to a Part field
See gh-27830
2022-04-28 10:45:09 +01:00
rstoyanchev b30f4d7bb7 Exposes all root causes to ExceptionHandler methods
Closes gh-28155
2022-04-28 04:04:57 +01:00
Arjen Poutsma b6b03f38d7 Updated .sdkmanrc 2022-04-26 11:54:02 +02:00
Stephane Nicoll 46b0d7dc03 Merge pull request #28369 from izeye
* pr/28369:
  Add Javadoc since for GraphQL constants

Closes gh-28369
2022-04-24 10:05:28 +02:00
izeye fcf64798b5 Add Javadoc since for GraphQL constants
See gh-28369
2022-04-24 09:58:50 +02:00
Stephane Nicoll 94ed07d9cb Merge pull request #28372 from zhangmingqi09
* pr/28372:
  Update copyright year of changed file
  Fix github issue reference in RequestMappingHandlerMapping

Closes gh-28372
2022-04-24 09:57:02 +02:00
Stephane Nicoll b81c62d064 Update copyright year of changed file
See gh-28372
2022-04-24 09:56:39 +02:00
zhangmingqi09 ca1a11acac Fix github issue reference in RequestMappingHandlerMapping
See gh-28372
2022-04-24 09:55:20 +02:00
Stephane Nicoll c261d40610 Merge pull request #28340 from koenpunt
* pr/28340:
  Update copyright year of changed file
  Fix method reference in Kotlin documentation

Closes gh-28340
2022-04-14 14:11:28 +02:00
Stephane Nicoll 3017955eff Update copyright year of changed file
See gh-28340
2022-04-14 14:09:54 +02:00
Koen Punt 22c82ff206 Fix method reference in Kotlin documentation
See gh-28340
2022-04-14 14:09:02 +02:00
Jerome Prinet f54952481b Update Gradle Enterprise plugin to 3.9
Closes gh-28338
2022-04-14 11:04:22 +02:00
Spring Builds 9e733b09e2 Next development version (v5.3.20-SNAPSHOT) 2022-04-13 09:24:33 +00:00
Sam Brannen a7cf19cec5 Improve documentation and matching algorithm in data binders 2022-04-13 09:55:40 +02:00
Juergen Hoeller 0cf7f7bd89 Polishing 2022-04-13 00:24:23 +02:00
Juergen Hoeller 949c3d450c Align plain accessor check 2022-04-13 00:24:06 +02:00
Arjen Poutsma 3b4ae7b028 TomcatHttpHandlerAdapter continues after 0 bytes
This commit makes sure that TomcatServerHttpRequest::readFromInputStream
follows the same contract as the method it overrides, and returns
AbstractListenerReadPublisher.EMPTY_BUFFER when 0 bytes are read.

See gh-28241
2022-04-12 16:52:13 +02:00
Stephane Nicoll 8b39698553 Upgrade to Reactor 2020.0.18
Closes gh-28329
2022-04-12 15:53:10 +02:00
Sam Brannen 6fad00ed22 Ensure dynamic proxy with AOP introduction includes lambda interfaces
Closes gh-28209
2022-04-09 09:57:43 +02:00
Sam Brannen 5f6d8df34b Introduce isLambdaClass() as a public utility in ClassUtils
This commit extracts isLambda() from AopProxyUtils and makes it
publicly available as ClassUtils.isLambdaClass().

This is a prerequisite for gh-28209.
2022-04-09 09:57:43 +02:00
Juergen Hoeller 35de7e19ee Introduce initializer callback for Bean Validation Configuration
Closes gh-27956
2022-04-08 14:39:36 +02:00
Juergen Hoeller 10e979e58b Polishing 2022-04-08 14:37:41 +02:00
Juergen Hoeller 4143b445d6 Polishing 2022-04-08 13:04:14 +02:00
Juergen Hoeller eefdd2c768 Avoid return value reference in potentially cached MethodParameter instance
Closes gh-28232
2022-04-08 13:03:13 +02:00
Juergen Hoeller 9f91168396 Restore ability to configure setClassLoader methods
Closes gh-28269
2022-04-08 13:02:53 +02:00
Juergen Hoeller 7aed6279a2 Consistent fallback in case of fast-class generation failure
Closes gh-28138
2022-04-08 13:02:36 +02:00
Juergen Hoeller c3fe112fd7 Consistent use of getLocalAddr() without DNS lookups in request adapters
Closes gh-28280
2022-04-08 13:00:50 +02:00
Juergen Hoeller 90103b0ae9 Consistent support for direct column matches in DataClassRowMapper
Closes gh-28243
2022-04-08 13:00:31 +02:00
Juergen Hoeller 0cf15c0fdd Upgrade to Tomcat 9.0.62, Jetty 9.4.46, Jetty Reactive HttpClient 1.1.11, Undertow 2.2.17, R2DBC Arabba-SR13, RSocket 1.1.2, OpenPDF 1.3.27, HtmlUnit 2.60, Checkstyle 10.1 2022-04-08 13:00:20 +02:00
Stephane Nicoll 4e9af3e277 Upgrade Java 18 in CI image 2022-04-07 08:52:43 +02:00
Stephane Nicoll 01fd489b47 Upgrade Ubuntu version in CI images 2022-04-07 08:51:48 +02:00
Brian Clozel 270b167e08 Upgrade registry-image-resource in CI pipeline to 1.5.0
See spring-projects/spring-boot#30408
2022-04-04 19:01:03 +02:00
GatinMI b158110801 Fix debug log for no matching acceptableTypes 2022-04-04 18:29:01 +02:00
Brian Clozel 17f7a24118 Add application/graphql+json mime and media types
Closes gh-28271
2022-04-01 19:24:55 +02:00
rstoyanchev d518a7d8c8 AbstractListenerReadPublisher continues after 0 bytes
If we read 0 bytes, e.g. chunked encoding markup read but not the
actual data within it, don't stop reading since the server may or
may not consider it necessary to call onDataAvailable again.
Instead, we keep on reading, and although isReady likely returns
false on the next iteration, it eliminates ambiguity and ensures
the server will call onDataAvailable when more data arrives.

Closes gh-28241
2022-04-01 17:38:03 +01:00
rstoyanchev 24cd3c1f4c Revert "Disable flaky integration tests for now"
This reverts commit 1627f57f1f in
preparation for fixing the root cause
2022-04-01 16:07:05 +01:00
Spring Builds 2a8c369cff Next development version (v5.3.19-SNAPSHOT) 2022-03-31 09:04:49 +00:00
922 changed files with 8259 additions and 5124 deletions
@@ -1,6 +1,9 @@
name: "Validate Gradle Wrapper"
on: [push, pull_request]
permissions:
contents: read
jobs:
validation:
name: "Validation"
+1
View File
@@ -21,6 +21,7 @@ classes/
/build
buildSrc/build
/spring-*/build
/spring-core/graalvm/build
/spring-core/kotlin-coroutines/build
/framework-bom/build
/integration-tests/build
+32 -22
View File
@@ -1,23 +1,33 @@
Juergen Hoeller <jhoeller@pivotal.io> jhoeller <jhoeller@vmware.com>
<jhoeller@pivotal.io> <jhoeller@vmware.com>
<jhoeller@pivotal.io> <jhoeller@gopivotal.com>
<rstoyanchev@pivotal.io> <rstoyanchev@vmware.com>
<rstoyanchev@pivotal.io> <rstoyanchev@gopivotal.com>
<pwebb@pivotal.io> <pwebb@vmware.com>
<pwebb@pivotal.io> <pwebb@gopivotal.com>
<cbeams@pivotal.io> <cbeams@vmware.com>
<cbeams@pivotal.io> <cbeams@gopivotal.com>
<cbeams@pivotal.io> <cbeams@gmail.com>
<apoutsma@pivotal.io> <apoutsma@vmware.com>
<apoutsma@pivotal.io> <apoutsma@gopivotal.com>
<apoutsma@pivotal.io> <poutsma@mac.com>
<ogierke@pivotal.io> <ogierke@vmware.com>
<ogierke@pivotal.io> <ogierke@gopivotal.com>
<dsyer@pivotal.io> <dsyer@vmware.com>
<dsyer@pivotal.io> <dsyer@gopivotal.com>
<dsyer@pivotal.io> <david_syer@hotmail.com>
<aclement@pivotal.io> <aclement@vmware.com>
<aclement@pivotal.io> <aclement@gopivotal.com>
<aclement@pivotal.io> <andrew.clement@gmail.com>
Juergen Hoeller <jhoeller@vmware.com>
Juergen Hoeller <jhoeller@vmware.com> <jhoeller@pivotal.io>
Juergen Hoeller <jhoeller@vmware.com> <jhoeller@gopivotal.com>
Rossen Stoyanchev <rstoyanchev@vmware.com>
Rossen Stoyanchev <rstoyanchev@vmware.com> <rstoyanchev@pivotal.io>
Rossen Stoyanchev <rstoyanchev@vmware.com> <rstoyanchev@gopivotal.com>
Phillip Webb <pwebb@vmware.com>
Phillip Webb <pwebb@vmware.com> <pwebb@pivotal.io>
Phillip Webb <pwebb@vmware.com> <pwebb@gopivotal.com>
Chris Beams <cbeams@vmware.com>
Chris Beams <cbeams@vmware.com> <cbeams@pivotal.io>
Chris Beams <cbeams@vmware.com> <cbeams@gopivotal.com>
Arjen Poutsma <apoutsma@vmware.com>
Arjen Poutsma <apoutsma@vmware.com> <apoutsma@pivotal.io>
Arjen Poutsma <apoutsma@vmware.com> <apoutsma@gopivotal.com>
Arjen Poutsma <apoutsma@vmware.com> <poutsma@mac.com>
Oliver Drotbohm <odrotbohm@vmware.com>
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@vmware.com>
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@pivotal.io>
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@gopivotal.com>
Dave Syer <dsyer@vmware.com>
Dave Syer <dsyer@vmware.com> <dsyer@pivotal.io>
Dave Syer <dsyer@vmware.com> <dsyer@gopivotal.com>
Dave Syer <dsyer@vmware.com> <david_syer@hotmail.com>
Andy Clement <aclement@vmware.com>
Andy Clement <aclement@vmware.com> <aclement@pivotal.io>
Andy Clement <aclement@vmware.com> <aclement@gopivotal.com>
Andy Clement <aclement@vmware.com> <andrew.clement@gmail.com>
Sam Brannen <sbrannen@vmware.com>
Sam Brannen <sbrannen@vmware.com> <sbrannen@pivotal.io>
Sam Brannen <sbrannen@vmware.com> <sam@sambrannen.com>
<dmitry.katsubo@gmail.com> <dmitry.katsubo@gmai.com>
Nick Williams <nicholas@nicholaswilliams.net> Nicholas Williams <nicholas@nicholaswilliams.net>
Nick Williams <nicholas@nicholaswilliams.net>
+1 -1
View File
@@ -1,3 +1,3 @@
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=8.0.322-librca
java=8.0.345-librca
+3 -3
View File
@@ -14,16 +14,16 @@ For access to artifacts or a distribution zip, see the [Spring Framework Artifac
## Documentation
The Spring Framework maintains reference documentation ([published](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/) and [source](src/docs/asciidoc)), Github [wiki pages](https://github.com/spring-projects/spring-framework/wiki), and an
The Spring Framework maintains reference documentation ([published](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/) and [source](src/docs/asciidoc)), GitHub [wiki pages](https://github.com/spring-projects/spring-framework/wiki), and an
[API reference](https://docs.spring.io/spring-framework/docs/current/javadoc-api/). There are also [guides and tutorials](https://spring.io/guides) across Spring projects.
## Micro-Benchmarks
See the [Micro-Benchmarks](https://github.com/spring-projects/spring-framework/wiki/Micro-Benchmarks) Wiki page.
See the [Micro-Benchmarks](https://github.com/spring-projects/spring-framework/wiki/Micro-Benchmarks) wiki page.
## Build from Source
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source) Wiki page and the [CONTRIBUTING.md](CONTRIBUTING.md) file.
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source) wiki page and the [CONTRIBUTING.md](CONTRIBUTING.md) file.
## Continuous Integration Builds
+29 -27
View File
@@ -27,19 +27,19 @@ configure(allprojects) { project ->
dependencyManagement {
imports {
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.6"
mavenBom "io.netty:netty-bom:4.1.75.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.17"
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR12"
mavenBom "io.rsocket:rsocket-bom:1.1.1"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.45.v20220203"
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.7"
mavenBom "io.netty:netty-bom:4.1.82.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.23"
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR13"
mavenBom "io.rsocket:rsocket-bom:1.1.3"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.48.v20220622"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.32"
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2"
mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.2"
mavenBom "org.junit:junit-bom:5.8.2"
}
dependencies {
dependencySet(group: 'org.apache.logging.log4j', version: '2.17.2') {
dependencySet(group: 'org.apache.logging.log4j', version: '2.18.0') {
entry 'log4j-api'
entry 'log4j-core'
entry 'log4j-jul'
@@ -67,8 +67,8 @@ configure(allprojects) { project ->
dependency "io.reactivex:rxjava:1.3.8"
dependency "io.reactivex:rxjava-reactive-streams:1.2.1"
dependency "io.reactivex.rxjava2:rxjava:2.2.21"
dependency "io.reactivex.rxjava3:rxjava:3.1.3"
dependency "io.smallrye.reactive:mutiny:1.4.0"
dependency "io.reactivex.rxjava3:rxjava:3.1.5"
dependency "io.smallrye.reactive:mutiny:1.7.0"
dependency "io.projectreactor.tools:blockhound:1.0.6.RELEASE"
dependency "com.caucho:hessian:4.0.63"
@@ -79,11 +79,11 @@ configure(allprojects) { project ->
dependency "com.google.code.gson:gson:2.8.9"
dependency "com.google.protobuf:protobuf-java-util:3.19.3"
dependency "com.googlecode.protobuf-java-format:protobuf-java-format:1.4"
dependency("com.thoughtworks.xstream:xstream:1.4.18") {
dependency("com.thoughtworks.xstream:xstream:1.4.19") {
exclude group: "xpp3", name: "xpp3_min"
exclude group: "xmlpull", name: "xmlpull"
}
dependency "org.apache.johnzon:johnzon-jsonb:1.2.16"
dependency "org.apache.johnzon:johnzon-jsonb:1.2.18"
dependency("org.codehaus.jettison:jettison:1.3.8") {
exclude group: "stax", name: "stax-api"
}
@@ -94,9 +94,9 @@ configure(allprojects) { project ->
dependency "org.ogce:xpp3:1.1.6"
dependency "org.yaml:snakeyaml:1.30"
dependency "com.h2database:h2:2.1.210"
dependency "com.h2database:h2:2.1.214"
dependency "com.github.ben-manes.caffeine:caffeine:2.9.3"
dependency "com.github.librepdf:openpdf:1.3.26"
dependency "com.github.librepdf:openpdf:1.3.29"
dependency "com.rometools:rome:1.18.0"
dependency "commons-io:commons-io:2.5"
dependency "io.vavr:vavr:0.10.4"
@@ -124,22 +124,22 @@ configure(allprojects) { project ->
dependency "org.ehcache:jcache:1.0.1"
dependency "org.ehcache:ehcache:3.4.0"
dependency "org.hibernate:hibernate-core:5.4.33.Final"
dependency "org.hibernate:hibernate-validator:6.2.3.Final"
dependency "org.hibernate:hibernate-validator:6.2.5.Final"
dependency "org.webjars:webjars-locator-core:0.48"
dependency "org.webjars:underscorejs:1.8.3"
dependencySet(group: 'org.apache.tomcat', version: '9.0.60') {
dependencySet(group: 'org.apache.tomcat', version: '9.0.65') {
entry 'tomcat-util'
entry('tomcat-websocket') {
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
}
}
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.60') {
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.65') {
entry 'tomcat-embed-core'
entry 'tomcat-embed-websocket'
}
dependencySet(group: 'io.undertow', version: '2.2.16.Final') {
dependencySet(group: 'io.undertow', version: '2.2.19.Final') {
entry 'undertow-core'
entry('undertow-servlet') {
exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_4.0_spec"
@@ -150,7 +150,7 @@ configure(allprojects) { project ->
}
}
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.10"
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.12"
dependency 'org.apache.httpcomponents.client5:httpclient5:5.1.3'
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.1.3'
dependency("org.apache.httpcomponents:httpclient:4.5.13") {
@@ -188,17 +188,17 @@ configure(allprojects) { project ->
exclude group: "junit", name: "junit"
}
dependency "org.testng:testng:7.4.0"
dependency "org.junit.support:testng-engine:1.0.1"
dependency "org.hamcrest:hamcrest:2.1"
dependency "org.junit.support:testng-engine:1.0.4"
dependency "org.hamcrest:hamcrest:2.2"
dependency "org.awaitility:awaitility:3.1.6"
dependency "org.assertj:assertj-core:3.22.0"
dependency "org.assertj:assertj-core:3.23.0"
dependencySet(group: 'org.xmlunit', version: '2.9.0') {
entry 'xmlunit-assertj'
entry('xmlunit-matchers') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
}
dependencySet(group: 'org.mockito', version: '4.4.0') {
dependencySet(group: 'org.mockito', version: '4.6.1') {
entry('mockito-core') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
@@ -206,10 +206,10 @@ configure(allprojects) { project ->
}
dependency "io.mockk:mockk:1.12.1"
dependency("net.sourceforge.htmlunit:htmlunit:2.59.0") {
dependency("net.sourceforge.htmlunit:htmlunit:2.64.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:htmlunit-driver:2.59.0") {
dependency("org.seleniumhq.selenium:htmlunit-driver:2.64.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
@@ -217,8 +217,8 @@ configure(allprojects) { project ->
exclude group: "io.netty", name: "netty"
}
dependency "org.skyscreamer:jsonassert:1.5.0"
dependency "com.jayway.jsonpath:json-path:2.6.0"
dependency "org.bouncycastle:bcpkix-jdk15on:1.66"
dependency "com.jayway.jsonpath:json-path:2.7.0"
dependency "org.bouncycastle:bcpkix-jdk18on:1.71"
dependencySet(group: 'org.apache.tiles', version: '3.0.8') {
entry 'tiles-api'
@@ -340,7 +340,7 @@ configure([rootProject] + javaProjects) { project ->
}
checkstyle {
toolVersion = "9.3"
toolVersion = "10.3.3"
configDirectory.set(rootProject.file("src/checkstyle"))
}
@@ -413,6 +413,8 @@ configure(rootProject) {
nohttp {
source.exclude "**/test-output/**"
source.exclude "spring-core/graalvm/build/**" // only available on `main`
source.exclude "spring-core-test/build/**" // only available on `main`
allowlistFile = project.file("src/nohttp/allowlist.lines")
def rootPath = file(rootDir).toPath()
def projectDirs = allprojects.collect { it.projectDir } + "${rootDir}/buildSrc"
+1 -1
View File
@@ -1,4 +1,4 @@
FROM ubuntu:focal-20220302
FROM ubuntu:focal-20220826
ADD setup.sh /setup.sh
ADD get-jdk-url.sh /get-jdk-url.sh
+9 -9
View File
@@ -3,18 +3,18 @@ set -e
case "$1" in
java8)
echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u322-b06/OpenJDK8U-jdk_x64_linux_hotspot_8u322b06.tar.gz"
echo "https://github.com/bell-sw/Liberica/releases/download/8u345+1/bellsoft-jdk8u345+1-linux-amd64.tar.gz"
;;
java11)
echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.14.1%2B1/OpenJDK11U-jdk_x64_linux_hotspot_11.0.14.1_1.tar.gz"
echo "https://github.com/bell-sw/Liberica/releases/download/11.0.16+8/bellsoft-jdk11.0.16+8-linux-amd64.tar.gz"
;;
java17)
echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.2%2B8/OpenJDK17U-jdk_x64_linux_hotspot_17.0.2_8.tar.gz"
;;
java18)
echo "https://github.com/adoptium/temurin18-binaries/releases/download/jdk18-2022-02-12-08-06-beta/OpenJDK18-jdk_x64_linux_hotspot_2022-02-12-08-06.tar.gz"
;;
*)
java17)
echo "https://github.com/bell-sw/Liberica/releases/download/17.0.4+8/bellsoft-jdk17.0.4+8-linux-amd64.tar.gz"
;;
java18)
echo "https://github.com/bell-sw/Liberica/releases/download/18.0.2+10/bellsoft-jdk18.0.2+10-linux-amd64.tar.gz"
;;
*)
echo $"Unknown java version"
exit 1
esac
-2
View File
@@ -14,8 +14,6 @@ rm -rf /var/lib/apt/lists/*
curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.4/concourse-java.sh > /opt/concourse-java.sh
curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/io/spring/concourse/releasescripts/concourse-release-scripts/0.3.2/concourse-release-scripts-0.3.2.jar
###########################################################
# JAVA
###########################################################
+4
View File
@@ -1,5 +1,6 @@
github-repo: "https://github.com/spring-projects/spring-framework.git"
github-repo-name: "spring-projects/spring-framework"
sonatype-staging-profile: "org.springframework"
docker-hub-organization: "springci"
artifactory-server: "https://repo.spring.io"
branch: "5.3.x"
@@ -7,4 +8,7 @@ milestone: "5.3.x"
build-name: "spring-framework"
pipeline-name: "spring-framework"
concourse-url: "https://ci.spring.io"
registry-mirror-host: docker.repo.spring.io
registry-mirror-username: ((artifactory-username))
registry-mirror-password: ((artifactory-password))
task-timeout: 1h00m
+23 -10
View File
@@ -12,7 +12,7 @@ anchors:
SONATYPE_USERNAME: ((sonatype-username))
SONATYPE_PASSWORD: ((sonatype-password))
SONATYPE_URL: ((sonatype-url))
SONATYPE_STAGING_PROFILE_ID: ((sonatype-staging-profile-id))
SONATYPE_STAGING_PROFILE: ((sonatype-staging-profile))
artifactory-task-params: &artifactory-task-params
ARTIFACTORY_SERVER: ((artifactory-server))
ARTIFACTORY_USERNAME: ((artifactory-username))
@@ -24,6 +24,10 @@ anchors:
username: ((docker-hub-username))
password: ((docker-hub-password))
tag: ((milestone))
registry-mirror-vars: &registry-mirror-vars
registry-mirror-host: ((registry-mirror-host))
registry-mirror-username: ((registry-mirror-username))
registry-mirror-password: ((registry-mirror-password))
slack-fail-params: &slack-fail-params
text: >
:concourse-failed: <https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!>
@@ -41,6 +45,11 @@ anchors:
GITHUB_TOKEN: ((github-ci-release-token))
resource_types:
- name: registry-image
type: registry-image
source:
repository: concourse/registry-image-resource
tag: 1.5.0
- name: artifactory-resource
type: registry-image
source:
@@ -87,7 +96,7 @@ resources:
branch: ((branch))
paths: ["ci/images/*"]
- name: ci-image
type: docker-image
type: registry-image
icon: docker
source:
<<: *docker-resource-source
@@ -157,13 +166,20 @@ resources:
jobs:
- name: build-ci-images
plan:
- get: ci-images-git-repo
trigger: true
- in_parallel:
- get: git-repo
- get: ci-images-git-repo
trigger: true
- task: build-ci-image
privileged: true
file: git-repo/ci/tasks/build-ci-image.yml
output_mapping:
image: ci-image
vars:
ci-image-name: ci-image
<<: *registry-mirror-vars
- put: ci-image
params:
build: ci-images-git-repo/ci/images
dockerfile: ci-images-git-repo/ci/images/ci-image/Dockerfile
image: ci-image/image.tar
- name: build
serial: true
public: true
@@ -340,7 +356,6 @@ jobs:
download_artifacts: false
save_build_info: true
- task: promote
image: ci-image
file: git-repo/ci/tasks/promote-version.yml
params:
RELEASE_TYPE: M
@@ -385,7 +400,6 @@ jobs:
download_artifacts: false
save_build_info: true
- task: promote
image: ci-image
file: git-repo/ci/tasks/promote-version.yml
params:
RELEASE_TYPE: RC
@@ -430,7 +444,6 @@ jobs:
download_artifacts: true
save_build_info: true
- task: promote
image: ci-image
file: git-repo/ci/tasks/promote-version.yml
params:
RELEASE_TYPE: RELEASE
+2 -2
View File
@@ -6,11 +6,11 @@ CONFIG_DIR=git-repo/ci/config
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
java -jar /opt/concourse-release-scripts.jar \
java -jar /concourse-release-scripts.jar \
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
publishToCentral $RELEASE_TYPE $BUILD_INFO_LOCATION artifactory-repo || { exit 1; }
java -jar /opt/concourse-release-scripts.jar \
java -jar /concourse-release-scripts.jar \
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
-8
View File
@@ -1,8 +0,0 @@
#!/bin/bash
export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
java -jar /opt/concourse-release-scripts.jar syncToCentral "RELEASE" $BUILD_INFO_LOCATION || { exit 1; }
echo "Sync complete"
echo $version > version/version
+31
View File
@@ -0,0 +1,31 @@
---
platform: linux
image_resource:
type: registry-image
source:
repository: concourse/oci-build-task
tag: 0.9.1
registry_mirror:
host: ((registry-mirror-host))
username: ((registry-mirror-username))
password: ((registry-mirror-password))
inputs:
- name: ci-images-git-repo
outputs:
- name: image
caches:
- path: ci-image-cache
params:
CONTEXT: ci-images-git-repo/ci/images
DOCKERFILE: ci-images-git-repo/ci/images/ci-image/Dockerfile
DOCKER_HUB_AUTH: ((docker-hub-auth))
run:
path: /bin/sh
args:
- "-c"
- |
mkdir -p /root/.docker
cat > /root/.docker/config.json <<EOF
{ "auths": { "https://index.docker.io/v1/": { "auth": "$DOCKER_HUB_AUTH" }}}
EOF
build
+6 -1
View File
@@ -1,5 +1,10 @@
---
platform: linux
image_resource:
type: registry-image
source:
repository: springio/concourse-release-scripts
tag: '0.3.4'
inputs:
- name: git-repo
- name: artifactory-repo
@@ -13,6 +18,6 @@ params:
SONATYPE_USER:
SONATYPE_PASSWORD:
SONATYPE_URL:
SONATYPE_STAGING_PROFILE_ID:
SONATYPE_STAGING_PROFILE:
run:
path: git-repo/ci/scripts/promote-version.sh
+3 -3
View File
@@ -1,5 +1,5 @@
version=5.3.18-SNAPSHOT
org.gradle.jvmargs=-Xmx1536M
version=5.3.23
org.gradle.jvmargs=-Xmx2048m
org.gradle.caching=true
org.gradle.parallel=true
kotlin.stdlib.default.dependency=false
kotlin.stdlib.default.dependency=false
+1 -1
View File
@@ -153,7 +153,7 @@ asciidoctorPdf {
task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dokkaHtmlMultiModule']) {
group = "Distribution"
description = "Builds -${archiveClassifier} archive containing api and reference " +
"for deployment at https://docs.spring.io/spring-framework/docs."
"for deployment at https://docs.spring.io/spring-framework/docs/."
archiveBaseName.set("spring-framework")
archiveClassifier.set("docs")
+2
View File
@@ -72,6 +72,7 @@ eclipse.classpath.file.whenMerged {
// Include project specific settings
task eclipseSettings(type: Copy) {
from rootProject.files(
'src/eclipse/org.eclipse.core.resources.prefs',
'src/eclipse/org.eclipse.jdt.core.prefs',
'src/eclipse/org.eclipse.jdt.ui.prefs')
into project.file('.settings/')
@@ -79,6 +80,7 @@ task eclipseSettings(type: Copy) {
}
task cleanEclipseSettings(type: Delete) {
delete project.file('.settings/org.eclipse.core.resources.prefs')
delete project.file('.settings/org.eclipse.jdt.core.prefs')
delete project.file('.settings/org.eclipse.jdt.ui.prefs')
}
+1 -1
View File
@@ -31,6 +31,6 @@ You'll notice these files are already intentionally in .gitignore. The same poli
## FAQ
Q. What about IntelliJ IDEA's own [Gradle support](https://confluence.jetbrains.net/display/IDEADEV/Gradle+integration)?
Q. What about IntelliJ IDEA's own [Gradle support](https://www.jetbrains.com/help/idea/gradle.html)?
A. Keep an eye on https://youtrack.jetbrains.com/issue/IDEA-53476
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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,7 +28,7 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatException;
/**
* Integration tests for advice invocation order for advice configured via the
@@ -52,7 +52,7 @@ class AopNamespaceHandlerAdviceOrderIntegrationTests {
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after", "after returning");
aspect.invocations.clear();
assertThatExceptionOfType(Exception.class).isThrownBy(() -> echo.echo(new Exception()));
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after", "after throwing");
}
}
@@ -69,7 +69,7 @@ class AopNamespaceHandlerAdviceOrderIntegrationTests {
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after returning", "after");
aspect.invocations.clear();
assertThatExceptionOfType(Exception.class).isThrownBy(() -> echo.echo(new Exception()));
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after throwing", "after");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -38,7 +38,7 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatException;
/**
* Integration tests for advice invocation order for advice configured via
@@ -65,8 +65,7 @@ class AspectJAutoProxyAdviceOrderIntegrationTests {
assertThat(aspect.invocations).containsExactly("around - start", "before", "after returning", "after", "around - end");
aspect.invocations.clear();
assertThatExceptionOfType(Exception.class).isThrownBy(
() -> echo.echo(new Exception()));
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
assertThat(aspect.invocations).containsExactly("around - start", "before", "after throwing", "after", "around - end");
}
}
@@ -95,8 +94,7 @@ class AspectJAutoProxyAdviceOrderIntegrationTests {
assertThat(aspect.invocations).containsExactly("around - start", "before", "after returning", "after", "around - end");
aspect.invocations.clear();
assertThatExceptionOfType(Exception.class).isThrownBy(
() -> echo.echo(new Exception()));
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
assertThat(aspect.invocations).containsExactly("around - start", "before", "after throwing", "after", "around - end");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -34,7 +34,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Repository;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatException;
/**
* Integration tests for the @EnableCaching annotation.
@@ -62,8 +62,7 @@ class EnableCachingIntegrationTests {
// this test is a bit fragile, but gets the job done, proving that an
// attempt was made to look up the AJ aspect. It's due to classpath issues
// in .integration-tests that it's not found.
assertThatExceptionOfType(Exception.class).isThrownBy(
ctx::refresh)
assertThatException().isThrownBy(ctx::refresh)
.withMessageContaining("AspectJCachingConfiguration");
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -45,7 +45,7 @@ import org.springframework.transaction.interceptor.BeanFactoryTransactionAttribu
import org.springframework.transaction.testfixture.CallCountingTransactionManager;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatException;
/**
* Integration tests for the @EnableTransactionManagement annotation.
@@ -98,7 +98,7 @@ class EnableTransactionManagementIntegrationTests {
// this test is a bit fragile, but gets the job done, proving that an
// attempt was made to look up the AJ aspect. It's due to classpath issues
// in .integration-tests that it's not found.
assertThatExceptionOfType(Exception.class)
assertThatException()
.isThrownBy(ctx::refresh)
.withMessageContaining("AspectJJtaTransactionManagementConfiguration");
}
+2 -2
View File
@@ -7,8 +7,8 @@ pluginManagement {
}
plugins {
id "com.gradle.enterprise" version "3.8.1"
id "io.spring.ge.conventions" version "0.0.9"
id "com.gradle.enterprise" version "3.10.2"
id "io.spring.ge.conventions" version "0.0.10"
}
include "spring-aop"
@@ -63,7 +63,7 @@ public interface Joinpoint {
/**
* Return the static part of this joinpoint.
* <p>The static part is an accessible object on which a chain of
* interceptors are installed.
* interceptors is installed.
*/
@Nonnull
AccessibleObject getStaticPart();
@@ -36,7 +36,7 @@ public interface IntroductionAwareMethodMatcher extends MethodMatcher {
* @param targetClass the target class
* @param hasIntroductions {@code true} if the object on whose behalf we are
* asking is the subject on one or more introductions; {@code false} otherwise
* @return whether or not this method matches statically
* @return whether this method matches statically
*/
boolean matches(Method method, Class<?> targetClass, boolean hasIntroductions);
@@ -60,7 +60,7 @@ public interface MethodMatcher {
* will be made.
* @param method the candidate method
* @param targetClass the target class
* @return whether or not this method matches statically
* @return whether this method matches statically
*/
boolean matches(Method method, Class<?> targetClass);
@@ -70,7 +70,7 @@ public interface MethodMatcher {
* runtime even if the 2-arg matches method returns {@code true}?
* <p>Can be invoked when an AOP proxy is created, and need not be invoked
* again before each method invocation,
* @return whether or not a runtime match via the 3-arg
* @return whether a runtime match via the 3-arg
* {@link #matches(java.lang.reflect.Method, Class, Object[])} method
* is required if static matching passed
*/
@@ -18,7 +18,7 @@ package org.springframework.aop;
/**
* Marker interface implemented by all AOP proxies. Used to detect
* whether or not objects are Spring-generated proxies.
* whether objects are Spring-generated proxies.
*
* @author Rob Harrop
* @since 2.0.1
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -368,7 +368,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
* to which argument name. There are multiple strategies for determining
* this binding, which are arranged in a ChainOfResponsibility.
*/
public final synchronized void calculateArgumentBindings() {
public final void calculateArgumentBindings() {
// The simple case... nothing to bind.
if (this.argumentsIntrospected || this.parameterTypes.length == 0) {
return;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -378,7 +378,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
}
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to evaluate join point for arguments " + Arrays.asList(args) +
logger.debug("Failed to evaluate join point for arguments " + Arrays.toString(args) +
" - falling back to non-match", ex);
}
return false;
@@ -39,7 +39,7 @@ import org.springframework.lang.Nullable;
public interface AspectJAdvisorFactory {
/**
* Determine whether or not the given class is an aspect, as reported
* Determine whether the given class is an aspect, as reported
* by AspectJ's {@link org.aspectj.lang.reflect.AjTypeSystem}.
* <p>Will simply return {@code false} if the supposed aspect is
* invalid (such as an extension of a concrete aspect class).
@@ -47,7 +47,7 @@ public interface AspectJAdvisorFactory {
* such as those with unsupported instantiation models.
* Use the {@link #validate} method to handle these cases if necessary.
* @param clazz the supposed annotation-style AspectJ class
* @return whether or not this class is recognized by AspectJ as an aspect class
* @return whether this class is recognized by AspectJ as an aspect class
*/
boolean isAspect(Class<?> clazz);
@@ -67,7 +67,7 @@ public class AspectMetadata implements Serializable {
/**
* Spring AOP pointcut corresponding to the per clause of the
* aspect. Will be the Pointcut.TRUE canonical instance in the
* aspect. Will be the {@code Pointcut.TRUE} canonical instance in the
* case of a singleton, otherwise an AspectJExpressionPointcut.
*/
private final Pointcut perClausePointcut;
@@ -60,8 +60,8 @@ public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProx
* <li>Otherwise the advice declared first gets highest precedence (i.e., runs
* first).</li>
* </ul>
* <p><b>Important:</b> Advisors are sorted in precedence order, from highest
* precedence to lowest. "On the way in" to a join point, the highest precedence
* <p><b>Important:</b> Advisors are sorted in precedence order, from the highest
* precedence to the lowest. "On the way in" to a join point, the highest precedence
* advisor should run first. "On the way out" of a join point, the highest
* precedence advisor should run last.
*/
@@ -314,7 +314,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
}
/**
* Add all of the given advisors to this proxy configuration.
* Add all the given advisors to this proxy configuration.
* @param advisors the advisors to register
*/
public void addAdvisors(Advisor... advisors) {
@@ -322,7 +322,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
}
/**
* Add all of the given advisors to this proxy configuration.
* Add all the given advisors to this proxy configuration.
* @param advisors the advisors to register
*/
public void addAdvisors(Collection<Advisor> advisors) {
@@ -134,7 +134,7 @@ public abstract class AopProxyUtils {
if (targetClass.isInterface()) {
advised.setInterfaces(targetClass);
}
else if (Proxy.isProxyClass(targetClass) || isLambda(targetClass)) {
else if (Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {
advised.setInterfaces(targetClass.getInterfaces());
}
specifiedInterfaces = advised.getProxiedInterfaces();
@@ -245,18 +245,4 @@ public abstract class AopProxyUtils {
return arguments;
}
/**
* Determine if the supplied {@link Class} is a JVM-generated implementation
* class for a lambda expression or method reference.
* <p>This method makes a best-effort attempt at determining this, based on
* checks that work on modern, main stream JVMs.
* @param clazz the class to check
* @return {@code true} if the class is a lambda implementation class
* @since 5.3.16
*/
static boolean isLambda(Class<?> clazz) {
return (clazz.isSynthetic() && (clazz.getSuperclass() == Object.class) &&
(clazz.getInterfaces().length > 0) && clazz.getName().contains("$$Lambda"));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -375,6 +375,22 @@ class CglibAopProxy implements AopProxy, Serializable {
return false;
}
/**
* Invoke the given method with a CGLIB MethodProxy if possible, falling back
* to a plain reflection invocation in case of a fast-class generation failure.
*/
@Nullable
private static Object invokeMethod(@Nullable Object target, Method method, Object[] args, MethodProxy methodProxy)
throws Throwable {
try {
return methodProxy.invoke(target, args);
}
catch (CodeGenerationException ex) {
CglibMethodInvocation.logFastClassGenerationFailure(method);
return AopUtils.invokeJoinpointUsingReflection(target, method, args);
}
}
/**
* Process a return value. Wraps a return of {@code this} if necessary to be the
* {@code proxy} and also verifies that {@code null} is not returned as a primitive.
@@ -425,7 +441,7 @@ class CglibAopProxy implements AopProxy, Serializable {
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object retVal = methodProxy.invoke(this.target, args);
Object retVal = invokeMethod(this.target, method, args, methodProxy);
return processReturnType(proxy, this.target, method, retVal);
}
}
@@ -450,7 +466,7 @@ class CglibAopProxy implements AopProxy, Serializable {
Object oldProxy = null;
try {
oldProxy = AopContext.setCurrentProxy(proxy);
Object retVal = methodProxy.invoke(this.target, args);
Object retVal = invokeMethod(this.target, method, args, methodProxy);
return processReturnType(proxy, this.target, method, retVal);
}
finally {
@@ -478,7 +494,7 @@ class CglibAopProxy implements AopProxy, Serializable {
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object target = this.targetSource.getTarget();
try {
Object retVal = methodProxy.invoke(target, args);
Object retVal = invokeMethod(target, method, args, methodProxy);
return processReturnType(proxy, target, method, retVal);
}
finally {
@@ -508,7 +524,7 @@ class CglibAopProxy implements AopProxy, Serializable {
Object target = this.targetSource.getTarget();
try {
oldProxy = AopContext.setCurrentProxy(proxy);
Object retVal = methodProxy.invoke(target, args);
Object retVal = invokeMethod(target, method, args, methodProxy);
return processReturnType(proxy, target, method, retVal);
}
finally {
@@ -685,13 +701,7 @@ class CglibAopProxy implements AopProxy, Serializable {
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
try {
retVal = methodProxy.invoke(target, argsToUse);
}
catch (CodeGenerationException ex) {
CglibMethodInvocation.logFastClassGenerationFailure(method);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
retVal = invokeMethod(target, method, argsToUse, methodProxy);
}
else {
// We need to create a method invocation...
@@ -21,6 +21,7 @@ import java.lang.reflect.Proxy;
import org.springframework.aop.SpringProxy;
import org.springframework.core.NativeDetector;
import org.springframework.util.ClassUtils;
/**
* Default {@link AopProxyFactory} implementation, creating either a CGLIB proxy
@@ -60,7 +61,7 @@ public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || AopProxyUtils.isLambda(targetClass)) {
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
@@ -72,8 +72,8 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
* NOTE: We could avoid the code duplication between this class and the CGLIB
* proxies by refactoring "invoke" into a template method. However, this approach
* adds at least 10% performance overhead versus a copy-paste solution, so we sacrifice
* elegance for performance. (We have a good test suite to ensure that the different
* proxies behave the same :-)
* elegance for performance (we have a good test suite to ensure that the different
* proxies behave the same :-)).
* This way, we can also more easily take advantage of minor optimizations in each class.
*/
@@ -198,7 +198,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
// Get the interception chain for this method.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// Check whether we have any advice. If we don't, we can fall back on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -50,7 +50,7 @@ import org.springframework.util.ObjectUtils;
/**
* {@link org.springframework.beans.factory.FactoryBean} implementation that builds an
* AOP proxy based on beans in Spring {@link org.springframework.beans.factory.BeanFactory}.
* AOP proxy based on beans in a Spring {@link org.springframework.beans.factory.BeanFactory}.
*
* <p>{@link org.aopalliance.intercept.MethodInterceptor MethodInterceptors} and
* {@link org.springframework.aop.Advisor Advisors} are identified by a list of bean
@@ -61,10 +61,11 @@ import org.springframework.util.ObjectUtils;
*
* <p>Global interceptors and advisors can be added at the factory level. The specified
* ones are expanded in an interceptor list where an "xxx*" entry is included in the
* list, matching the given prefix with the bean names (e.g. "global*" would match
* both "globalBean1" and "globalBean2", "*" all defined interceptors). The matching
* interceptors get applied according to their returned order value, if they implement
* the {@link org.springframework.core.Ordered} interface.
* list, matching the given prefix with the bean names &mdash; for example, "global*"
* would match both "globalBean1" and "globalBean2"; whereas, "*" would match all
* defined interceptors. The matching interceptors get applied according to their
* returned order value, if they implement the {@link org.springframework.core.Ordered}
* interface.
*
* <p>Creates a JDK proxy when proxy interfaces are given, and a CGLIB proxy for the
* actual target class if not. Note that the latter will only work if the target class
@@ -75,7 +76,7 @@ import org.springframework.util.ObjectUtils;
* This won't work for existing prototype references, which are independent. However,
* it will work for prototypes subsequently obtained from the factory. Changes to
* interception will work immediately on singletons (including existing references).
* However, to change interfaces or target it's necessary to obtain a new instance
* However, to change interfaces or a target it's necessary to obtain a new instance
* from the factory. This means that singleton instances obtained from the factory
* do not have the same object identity. However, they do have the same interceptors
* and target, and changing any reference will change all objects.
@@ -406,7 +407,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
if (namedBeanClass != null) {
return (Advisor.class.isAssignableFrom(namedBeanClass) || Advice.class.isAssignableFrom(namedBeanClass));
}
// Treat it as an target bean if we can't tell.
// Treat it as a target bean if we can't tell.
if (logger.isDebugEnabled()) {
logger.debug("Could not determine type of bean with name '" + beanName +
"' - assuming it is neither an Advisor nor an Advice");
@@ -424,7 +425,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
if (!this.advisorChainInitialized && !ObjectUtils.isEmpty(this.interceptorNames)) {
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
"- cannot resolve interceptor names " + Arrays.toString(this.interceptorNames));
}
// Globals can't be last unless we specified a targetSource using the property...
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -50,6 +50,7 @@ import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostP
import org.springframework.core.SmartClassLoader;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
@@ -85,6 +86,7 @@ import org.springframework.util.StringUtils;
* @author Juergen Hoeller
* @author Rod Johnson
* @author Rob Harrop
* @author Sam Brannen
* @since 13.10.2003
* @see #setInterceptorNames
* @see #getAdvicesAndAdvisorsForBean
@@ -117,7 +119,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
/**
* Indicates whether or not the proxy should be frozen. Overridden from super
* Indicates whether the proxy should be frozen. Overridden from super
* to prevent the configuration from becoming frozen too early.
*/
private boolean freezeProxy = false;
@@ -143,9 +145,9 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
/**
* Set whether or not the proxy should be frozen, preventing advice
* Set whether the proxy should be frozen, preventing advice
* from being added to it once it is created.
* <p>Overridden from the super class to prevent the proxy configuration
* <p>Overridden from the superclass to prevent the proxy configuration
* from being frozen before the proxy is created.
*/
@Override
@@ -442,8 +444,8 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
proxyFactory.copyFrom(this);
if (proxyFactory.isProxyTargetClass()) {
// Explicit handling of JDK proxy targets (for introduction advice scenarios)
if (Proxy.isProxyClass(beanClass)) {
// Explicit handling of JDK proxy targets and lambdas (for introduction advice scenarios)
if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) {
// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
for (Class<?> ifc : beanClass.getInterfaces()) {
proxyFactory.addInterface(ifc);
@@ -56,7 +56,7 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
protected transient Log defaultLogger = LogFactory.getLog(getClass());
/**
* Indicates whether or not proxy class names should be hidden when using dynamic loggers.
* Indicates whether proxy class names should be hidden when using dynamic loggers.
* @see #setUseDynamicLogger
*/
private boolean hideProxyClassNames = false;
@@ -119,7 +119,7 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
/**
* Determines whether or not logging is enabled for the particular {@code MethodInvocation}.
* Determines whether logging is enabled for the particular {@code MethodInvocation}.
* If not, the method invocation proceeds as normal, otherwise the method invocation is passed
* to the {@code invokeUnderTrace} method for handling.
* @see #invokeUnderTrace(org.aopalliance.intercept.MethodInvocation, org.apache.commons.logging.Log)
@@ -36,7 +36,7 @@ public interface AsyncUncaughtExceptionHandler {
* Handle the given uncaught exception thrown from an asynchronous method.
* @param ex the exception thrown from the asynchronous method
* @param method the asynchronous method
* @param params the parameters used to invoked the method
* @param params the parameters used to invoke the method
*/
void handleUncaughtException(Throwable ex, Method method, Object... params);
@@ -217,7 +217,7 @@ public abstract class AopUtils {
* out a pointcut for a class.
* @param pc the static or dynamic pointcut to check
* @param targetClass the class to test
* @param hasIntroductions whether or not the advisor chain
* @param hasIntroductions whether the advisor chain
* for this bean includes any introductions
* @return whether the pointcut can apply on any method
*/
@@ -261,7 +261,7 @@ public abstract class AopUtils {
/**
* Can the given advisor apply at all on the given class?
* This is an important test as it can be used to optimize
* out a advisor for a class.
* out an advisor for a class.
* @param advisor the advisor to check
* @param targetClass class we're testing
* @return whether the pointcut can apply on any method
@@ -272,11 +272,11 @@ public abstract class AopUtils {
/**
* Can the given advisor apply at all on the given class?
* <p>This is an important test as it can be used to optimize out a advisor for a class.
* <p>This is an important test as it can be used to optimize out an advisor for a class.
* This version also takes into account introductions (for IntroductionAwareMethodMatchers).
* @param advisor the advisor to check
* @param targetClass class we're testing
* @param hasIntroductions whether or not the advisor chain for this bean includes
* @param hasIntroductions whether the advisor chain for this bean includes
* any introductions
* @return whether the pointcut can apply on any method
*/
@@ -43,7 +43,7 @@ public class DefaultPointcutAdvisor extends AbstractGenericPointcutAdvisor imple
/**
* Create an empty DefaultPointcutAdvisor.
* <p>Advice must be set before use using setter methods.
* <p>Advice must be set before using setter methods.
* Pointcut will normally be set also, but defaults to {@code Pointcut.TRUE}.
*/
public DefaultPointcutAdvisor() {
@@ -90,7 +90,7 @@ public abstract class MethodMatchers {
* @param targetClass the target class
* @param hasIntroductions {@code true} if the object on whose behalf we are
* asking is the subject on one or more introductions; {@code false} otherwise
* @return whether or not this method matches statically
* @return whether this method matches statically
*/
public static boolean matches(MethodMatcher mm, Method method, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(mm, "MethodMatcher must not be null");
@@ -37,7 +37,7 @@ import org.springframework.lang.Nullable;
* {@link AbstractPrototypeBasedTargetSource} can be used to create objects
* in order to put them into the pool.
*
* <p>Subclasses must also implement some of the monitoring methods from the
* <p>Subclasses must also implement some monitoring methods from the
* {@link PoolingConfig} interface. The {@link #getPoolingConfigMixin()} method
* makes these stats available on proxied objects through an IntroductionAdvisor.
*
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -142,11 +142,11 @@ public class TrickyAspectJPointcutExpressionTests {
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public static @interface Log {
@interface Log {
}
public static interface TestService {
public interface TestService {
public String sayHello();
}
@@ -931,7 +931,7 @@ abstract class AbstractMakeModifiable {
return setter.getDeclaringClass().getMethod(getterName);
}
catch (NoSuchMethodException ex) {
// must be write only
// must be write-only
return null;
}
}
@@ -19,7 +19,6 @@ package org.springframework.aop.framework;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
@@ -134,61 +133,4 @@ public class AopProxyUtilsTests {
AopProxyUtils.proxiedUserInterfaces(proxy));
}
@Test
void isLambda() {
assertIsLambda(AopProxyUtilsTests.staticLambdaExpression);
assertIsLambda(AopProxyUtilsTests::staticStringFactory);
assertIsLambda(this.instanceLambdaExpression);
assertIsLambda(this::instanceStringFactory);
}
@Test
void isNotLambda() {
assertIsNotLambda(new EnigmaSupplier());
assertIsNotLambda(new Supplier<String>() {
@Override
public String get() {
return "anonymous inner class";
}
});
assertIsNotLambda(new Fake$$LambdaSupplier());
}
private static void assertIsLambda(Supplier<String> supplier) {
assertThat(AopProxyUtils.isLambda(supplier.getClass())).isTrue();
}
private static void assertIsNotLambda(Supplier<String> supplier) {
assertThat(AopProxyUtils.isLambda(supplier.getClass())).isFalse();
}
private static final Supplier<String> staticLambdaExpression = () -> "static lambda expression";
private final Supplier<String> instanceLambdaExpression = () -> "instance lambda expressions";
private static String staticStringFactory() {
return "static string factory";
}
private String instanceStringFactory() {
return "instance string factory";
}
private static class EnigmaSupplier implements Supplier<String> {
@Override
public String get() {
return "enigma";
}
}
private static class Fake$$LambdaSupplier implements Supplier<String> {
@Override
public String get() {
return "fake lambda";
}
}
}
@@ -48,7 +48,7 @@ public class IntroductionBenchmarkTests {
}
}
public static interface Counter {
public interface Counter {
int getCount();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -44,7 +44,7 @@ import org.springframework.core.annotation.Order;
import org.springframework.core.testfixture.TimeStamped;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatRuntimeException;
/**
* Also tests AdvisedSupport and ProxyCreatorSupport superclasses.
@@ -277,7 +277,7 @@ public class ProxyFactoryTests {
assertThat(config.getAdvisors().length == oldCount).isTrue();
assertThatExceptionOfType(RuntimeException.class)
assertThatRuntimeException()
.as("Existing object won't implement this interface any more")
.isThrownBy(ts::getTimeStamp); // Existing reference will fail
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.jupiter.api.Test;
import org.springframework.aop.testfixture.advice.MyThrowsHandler;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatException;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.BDDMockito.given;
@@ -63,9 +64,7 @@ public class ThrowsAdviceInterceptorTests {
Exception ex = new Exception();
MethodInvocation mi = mock(MethodInvocation.class);
given(mi.proceed()).willThrow(ex);
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
ti.invoke(mi))
.isSameAs(ex);
assertThatException().isThrownBy(() -> ti.invoke(mi)).isSameAs(ex);
assertThat(th.getCalls()).isEqualTo(0);
}
@@ -307,7 +307,7 @@ public class DelegatingIntroductionInterceptorTests {
}
private static interface SubTimeStamped extends TimeStamped {
private interface SubTimeStamped extends TimeStamped {
}
}
@@ -35,7 +35,7 @@ public abstract aspect AbstractDependencyInjectionAspect {
mostSpecificSubTypeConstruction() && !preConstructionConfiguration();
/**
* Select least specific super type that is marked for DI
* Select least specific supertype that is marked for DI
* (so that injection occurs only once with pre-construction injection).
*/
public abstract pointcut leastSpecificSuperTypeConstruction();
@@ -26,7 +26,7 @@ import org.springframework.context.annotation.Import;
/**
* Signals the current application context to apply dependency injection to
* non-managed classes that are instantiated outside of the Spring bean factory
* non-managed classes that are instantiated outside the Spring bean factory
* (typically classes annotated with the
* {@link org.springframework.beans.factory.annotation.Configurable @Configurable}
* annotation).
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -22,7 +22,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.transaction.testfixture.CallCountingTransactionManager;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatException;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatRuntimeException;
/**
* @author Rod Johnson
@@ -104,44 +106,44 @@ public class TransactionAspectTests {
@Test
public void defaultCommitOnAnnotatedClass() throws Throwable {
Exception ex = new Exception();
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
testRollback(() -> annotationOnlyOnClassWithNoInterface.echo(ex), false))
assertThatException()
.isThrownBy(() -> testRollback(() -> annotationOnlyOnClassWithNoInterface.echo(ex), false))
.isSameAs(ex);
}
@Test
public void defaultRollbackOnAnnotatedClass() throws Throwable {
RuntimeException ex = new RuntimeException();
assertThatExceptionOfType(RuntimeException.class).isThrownBy(() ->
testRollback(() -> annotationOnlyOnClassWithNoInterface.echo(ex), true))
assertThatRuntimeException()
.isThrownBy(() -> testRollback(() -> annotationOnlyOnClassWithNoInterface.echo(ex), true))
.isSameAs(ex);
}
@Test
public void defaultCommitOnSubclassOfAnnotatedClass() throws Throwable {
Exception ex = new Exception();
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
testRollback(() -> new SubclassOfClassWithTransactionalAnnotation().echo(ex), false))
assertThatException()
.isThrownBy(() -> testRollback(() -> new SubclassOfClassWithTransactionalAnnotation().echo(ex), false))
.isSameAs(ex);
}
@Test
public void defaultCommitOnSubclassOfClassWithTransactionalMethodAnnotated() throws Throwable {
Exception ex = new Exception();
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
testRollback(() -> new SubclassOfClassWithTransactionalMethodAnnotation().echo(ex), false))
assertThatException()
.isThrownBy(() -> testRollback(() -> new SubclassOfClassWithTransactionalMethodAnnotation().echo(ex), false))
.isSameAs(ex);
}
@Test
public void noCommitOnImplementationOfAnnotatedInterface() throws Throwable {
final Exception ex = new Exception();
Exception ex = new Exception();
testNotTransactional(() -> new ImplementsAnnotatedInterface().echo(ex), ex);
}
@Test
public void noRollbackOnImplementationOfAnnotatedInterface() throws Throwable {
final Exception rollbackProvokingException = new RuntimeException();
Exception rollbackProvokingException = new RuntimeException();
testNotTransactional(() -> new ImplementsAnnotatedInterface().echo(rollbackProvokingException),
rollbackProvokingException);
}
@@ -165,8 +167,9 @@ public class TransactionAspectTests {
protected void testNotTransactional(TransactionOperationCallback toc, Throwable expected) throws Throwable {
txManager.clear();
assertThat(txManager.begun).isEqualTo(0);
assertThatExceptionOfType(Throwable.class).isThrownBy(
toc::performTransactionalOperation).isSameAs(expected);
assertThatExceptionOfType(Throwable.class)
.isThrownBy(toc::performTransactionalOperation)
.isSameAs(expected);
assertThat(txManager.begun).isEqualTo(0);
}
@@ -82,7 +82,7 @@ public interface BeanWrapper extends ConfigurablePropertyAccessor {
* Obtain the property descriptor for a specific property
* of the wrapped object.
* @param propertyName the property to obtain the descriptor for
* (may be a nested path, but no indexed/mapped property)
* (may be a nested path, but not an indexed/mapped property)
* @return the property descriptor for the specified property
* @throws InvalidPropertyException if there is no such property
*/
@@ -22,6 +22,7 @@ import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.security.ProtectionDomain;
import java.util.Collections;
import java.util.HashSet;
@@ -287,13 +288,17 @@ public final class CachedIntrospectionResults {
// This call is slow so we do it once.
PropertyDescriptor[] pds = this.beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
if (Class.class == beanClass && (!"name".equals(pd.getName()) && !pd.getName().endsWith("Name"))) {
if (Class.class == beanClass && !("name".equals(pd.getName()) ||
(pd.getName().endsWith("Name") && String.class == pd.getPropertyType()))) {
// Only allow all name variants of Class properties
continue;
}
if (pd.getPropertyType() != null && (ClassLoader.class.isAssignableFrom(pd.getPropertyType())
|| ProtectionDomain.class.isAssignableFrom(pd.getPropertyType()))) {
// Ignore ClassLoader and ProtectionDomain types - nobody needs to bind to those
if (URL.class == beanClass && "content".equals(pd.getName())) {
// Only allow URL attribute introspection, not content resolution
continue;
}
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType())) {
// Ignore read-only properties such as ClassLoader - no need to bind to those
continue;
}
if (logger.isTraceEnabled()) {
@@ -342,9 +347,8 @@ public final class CachedIntrospectionResults {
// GenericTypeAwarePropertyDescriptor leniently resolves a set* write method
// against a declared read method, so we prefer read method descriptors here.
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
if (pd.getPropertyType() != null && (ClassLoader.class.isAssignableFrom(pd.getPropertyType())
|| ProtectionDomain.class.isAssignableFrom(pd.getPropertyType()))) {
// Ignore ClassLoader and ProtectionDomain types - nobody needs to bind to those
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType())) {
// Ignore read-only properties such as ClassLoader - no need to bind to those
continue;
}
this.propertyDescriptors.put(pd.getName(), pd);
@@ -364,7 +368,7 @@ public final class CachedIntrospectionResults {
for (Method method : beanClass.getMethods()) {
if (!this.propertyDescriptors.containsKey(method.getName()) &&
!readMethodNames.contains((method.getName())) && isPlainAccessor(method)) {
!readMethodNames.contains(method.getName()) && isPlainAccessor(method)) {
this.propertyDescriptors.put(method.getName(),
new GenericTypeAwarePropertyDescriptor(beanClass, method.getName(), method, null, null));
readMethodNames.add(method.getName());
@@ -373,8 +377,10 @@ public final class CachedIntrospectionResults {
}
private boolean isPlainAccessor(Method method) {
if (method.getParameterCount() > 0 || method.getReturnType() == void.class ||
method.getDeclaringClass() == Object.class || Modifier.isStatic(method.getModifiers())) {
if (Modifier.isStatic(method.getModifiers()) ||
method.getDeclaringClass() == Object.class || method.getDeclaringClass() == Class.class ||
method.getParameterCount() > 0 || method.getReturnType() == void.class ||
isInvalidReadOnlyPropertyType(method.getReturnType())) {
return false;
}
try {
@@ -387,6 +393,12 @@ public final class CachedIntrospectionResults {
}
}
private boolean isInvalidReadOnlyPropertyType(@Nullable Class<?> returnType) {
return (returnType != null && (AutoCloseable.class.isAssignableFrom(returnType) ||
ClassLoader.class.isAssignableFrom(returnType) ||
ProtectionDomain.class.isAssignableFrom(returnType)));
}
BeanInfo getBeanInfo() {
return this.beanInfo;
@@ -327,7 +327,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
/**
* Register the specified property as "processed" in the sense
* of some processor calling the corresponding setter method
* outside of the PropertyValue(s) mechanism.
* outside the PropertyValue(s) mechanism.
* <p>This will lead to {@code true} being returned from
* a {@link #contains} call for the specified property.
* @param propertyName the name of the property.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2022 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.
@@ -23,8 +23,9 @@ import org.springframework.lang.Nullable;
/**
* Common interface for classes that can access named properties
* (such as bean properties of an object or fields in an object)
* Serves as base interface for {@link BeanWrapper}.
* (such as bean properties of an object or fields in an object).
*
* <p>Serves as base interface for {@link BeanWrapper}.
*
* @author Juergen Hoeller
* @since 1.1
@@ -22,7 +22,7 @@ package org.springframework.beans;
* {@link org.springframework.beans.PropertyEditorRegistry property editor registry}.
*
* <p>This is particularly useful when you need to use the same set of
* property editors in several different situations: write a corresponding
* property editors in several situations: write a corresponding
* registrar and reuse that in each case.
*
* @author Juergen Hoeller
@@ -45,7 +45,7 @@ import org.springframework.lang.Nullable;
*
* <p><b>The container is only responsible for managing the lifecycle of the FactoryBean
* instance, not the lifecycle of the objects created by the FactoryBean.</b> Therefore,
* a destroy method on an exposed bean object (such as {@link java.io.Closeable#close()}
* a destroy method on an exposed bean object (such as {@link java.io.Closeable#close()})
* will <i>not</i> be called automatically. Instead, a FactoryBean should implement
* {@link DisposableBean} and delegate any such close call to the underlying object.
*
@@ -108,7 +108,7 @@ public interface FactoryBean<T> {
* been fully initialized. It must not rely on state created during
* initialization; of course, it can still use such state if available.
* <p><b>NOTE:</b> Autowiring will simply ignore FactoryBeans that return
* {@code null} here. Therefore it is highly recommended to implement
* {@code null} here. Therefore, it is highly recommended to implement
* this method properly, using the current state of the FactoryBean.
* @return the type of object that this FactoryBean creates,
* or {@code null} if not known at the time of the call
@@ -343,7 +343,7 @@ public interface ListableBeanFactory extends BeanFactory {
/**
* Find an {@link Annotation} of {@code annotationType} on the specified bean,
* traversing its interfaces and super classes if no annotation can be found on
* traversing its interfaces and superclasses if no annotation can be found on
* the given class itself, as well as checking the bean's factory method (if any).
* @param beanName the name of the bean to look for annotations on
* @param annotationType the type of annotation to look for
@@ -361,7 +361,7 @@ public interface ListableBeanFactory extends BeanFactory {
/**
* Find an {@link Annotation} of {@code annotationType} on the specified bean,
* traversing its interfaces and super classes if no annotation can be found on
* traversing its interfaces and superclasses if no annotation can be found on
* the given class itself, as well as checking the bean's factory method (if any).
* @param beanName the name of the bean to look for annotations on
* @param annotationType the type of annotation to look for
@@ -137,7 +137,7 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
* as a <em>qualifier</em>, the bean must 'match' against the annotation as
* well as any attributes it may contain. The bean definition must contain
* the same qualifier or match by meta attributes. A "value" attribute will
* fallback to match against the bean name or an alias if a qualifier or
* fall back to match against the bean name or an alias if a qualifier or
* attribute does not match.
* @see Qualifier
*/
@@ -186,7 +186,7 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
if (isQualifier(metaType)) {
foundMeta = true;
// Only accept fallback match if @Qualifier annotation has a value...
// Otherwise it is just a marker for a custom qualifier annotation.
// Otherwise, it is just a marker for a custom qualifier annotation.
if ((fallbackToMeta && ObjectUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
!checkQualifier(bdHolder, metaAnn, typeConverter)) {
return false;
@@ -30,7 +30,7 @@ import org.springframework.beans.BeansException;
*
* <p>A {@code BeanFactoryPostProcessor} may interact with and modify bean
* definitions, but never bean instances. Doing so may cause premature bean
* instantiation, violating the container and causing unintended side-effects.
* instantiation, violating the container and causing unintended side effects.
* If bean instance interaction is required, consider implementing
* {@link BeanPostProcessor} instead.
*
@@ -65,7 +65,7 @@ public class ConstructorArgumentValues {
/**
* Copy all given argument values into this object, using separate holder
* instances to keep the values independent from the original object.
* instances to keep the values independent of the original object.
* <p>Note: Identical ValueHolder instances will only be registered once,
* to allow for merging and re-merging of argument value definitions. Distinct
* ValueHolder instances carrying the same content are of course allowed.
@@ -155,7 +155,7 @@ public abstract class YamlProcessor {
* resources. Each resource is parsed in turn and the documents inside checked against
* the {@link #setDocumentMatchers(DocumentMatcher...) matchers}. If a document
* matches it is passed into the callback, along with its representation as Properties.
* Depending on the {@link #setResolutionMethod(ResolutionMethod)} not all of the
* Depending on the {@link #setResolutionMethod(ResolutionMethod)} not all the
* documents will be parsed.
* @param callback a callback to delegate to once matching documents are found
* @see #createYaml()
@@ -124,7 +124,7 @@ public class BeanComponentDefinition extends BeanDefinitionHolder implements Com
}
/**
* This implementations expects the other object to be of type BeanComponentDefinition
* This implementation expects the other object to be of type BeanComponentDefinition
* as well, in addition to the superclass's equality requirements.
*/
@Override
@@ -50,13 +50,13 @@ import org.springframework.beans.factory.config.BeanReference;
* {@link #getBeanReferences}, tools may wish to inspect all {@link BeanDefinition BeanDefinitions} to gather
* the full set of {@link BeanReference BeanReferences}. Implementations are required to provide
* all {@link BeanReference BeanReferences} that are required to validate the configuration of the
* overall logical entity as well as those required to provide full user visualisation of the configuration.
* overall logical entity as well as those required to provide full user visualization of the configuration.
* It is expected that certain {@link BeanReference BeanReferences} will not be important to
* validation or to the user view of the configuration and as such these may be omitted. A tool may wish to
* display any additional {@link BeanReference BeanReferences} sourced through the supplied
* {@link BeanDefinition BeanDefinitions} but this is not considered to be a typical case.
*
* <p>Tools can determine the important of contained {@link BeanDefinition BeanDefinitions} by checking the
* <p>Tools can determine the importance of contained {@link BeanDefinition BeanDefinitions} by checking the
* {@link BeanDefinition#getRole role identifier}. The role is essentially a hint to the tool as to how
* important the configuration provider believes a {@link BeanDefinition} is to the end user. It is expected
* that tools will <strong>not</strong> display all {@link BeanDefinition BeanDefinitions} for a given
@@ -1,5 +1,5 @@
/**
* Support package for the Java 6 ServiceLoader facility.
* Support package for the Java {@link java.util.ServiceLoader} facility.
*/
@NonNullApi
@NonNullFields
@@ -1510,7 +1510,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
// even if it technically is an unsatisfied, non-simple property.
if (Object.class != pd.getPropertyType()) {
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
@@ -945,7 +945,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
}
/**
* Specify whether or not the configured initializer method is the default.
* Specify whether the configured initializer method is the default.
* <p>The default value is {@code true} for a locally specified init method
* but switched to {@code false} for a shared setting in a defaults section
* (e.g. {@code bean init-method} versus {@code beans default-init-method}
@@ -984,7 +984,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
}
/**
* Specify whether or not the configured destroy method is the default.
* Specify whether the configured destroy method is the default.
* <p>The default value is {@code true} for a locally specified destroy method
* but switched to {@code false} for a shared setting in a defaults section
* (e.g. {@code bean destroy-method} versus {@code beans default-destroy-method}
@@ -593,7 +593,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
// Setup the types that we want to match against
// Set up the types that we want to match against
Class<?> classToMatch = typeToMatch.resolve();
if (classToMatch == null) {
classToMatch = FactoryBean.class;
@@ -293,7 +293,7 @@ public final class BeanDefinitionBuilder {
}
/**
* Set whether or not this definition is abstract.
* Set whether this definition is abstract.
*/
public BeanDefinitionBuilder setAbstract(boolean flag) {
this.beanDefinition.setAbstract(flag);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -985,7 +985,7 @@ class ConstructorResolver {
/**
* Delegate for checking Java 6's {@link ConstructorProperties} annotation.
* Delegate for checking Java's {@link ConstructorProperties} annotation.
*/
private static class ConstructorPropertiesChecker {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -280,7 +280,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
/**
* Return the dependency comparator for this BeanFactory (may be {@code null}.
* Return the dependency comparator for this BeanFactory (may be {@code null}).
* @since 4.0
*/
@Nullable
@@ -585,7 +585,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
if (!matchFound) {
// In case of FactoryBean, try to match FactoryBean instance itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
}
if (matchFound) {
@@ -2165,20 +2167,25 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
@Nullable
public Object getOrderSource(Object obj) {
String beanName = this.instancesToBeanNames.get(obj);
if (beanName == null || !containsBeanDefinition(beanName)) {
if (beanName == null) {
return null;
}
RootBeanDefinition beanDefinition = getMergedLocalBeanDefinition(beanName);
List<Object> sources = new ArrayList<>(2);
Method factoryMethod = beanDefinition.getResolvedFactoryMethod();
if (factoryMethod != null) {
sources.add(factoryMethod);
try {
RootBeanDefinition beanDefinition = (RootBeanDefinition) getMergedBeanDefinition(beanName);
List<Object> sources = new ArrayList<>(2);
Method factoryMethod = beanDefinition.getResolvedFactoryMethod();
if (factoryMethod != null) {
sources.add(factoryMethod);
}
Class<?> targetType = beanDefinition.getTargetType();
if (targetType != null && targetType != obj.getClass()) {
sources.add(targetType);
}
return sources.toArray();
}
Class<?> targetType = beanDefinition.getTargetType();
if (targetType != null && targetType != obj.getClass()) {
sources.add(targetType);
catch (NoSuchBeanDefinitionException ex) {
return null;
}
return sources.toArray();
}
}
@@ -33,7 +33,7 @@ import org.springframework.util.ClassUtils;
/**
* Basic {@link AutowireCandidateResolver} that performs a full generic type
* match with the candidate's type if the dependency is declared as a generic type
* (e.g. Repository&lt;Customer&gt;).
* (e.g. {@code Repository<Customer>}).
*
* <p>This is the base class for
* {@link org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver},
@@ -17,7 +17,7 @@
package org.springframework.beans.factory.support;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.BeanMetadataElement;
@@ -31,6 +31,8 @@ import org.springframework.lang.Nullable;
* @author Rod Johnson
* @author Rob Harrop
* @author Juergen Hoeller
* @author Stephane Nicoll
* @author Sam Brannen
* @since 27.05.2003
* @param <E> the element type
*/
@@ -55,16 +57,16 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad
/**
* Return a new instance containing an arbitrary number of elements.
* Create a new instance containing an arbitrary number of elements.
* @param elements the elements to be contained in the list
* @param <E> the {@code List}'s element type
* @return a {@code List} containing the specified elements
* @return a {@code ManagedList} containing the specified elements
* @since 5.3.16
*/
@SuppressWarnings("unchecked")
@SafeVarargs
public static <E> ManagedList<E> of(E... elements) {
ManagedList<E> list = new ManagedList<>();
list.addAll(Arrays.asList(elements));
Collections.addAll(list, elements);
return list;
}
@@ -16,7 +16,7 @@
package org.springframework.beans.factory.support;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
@@ -30,6 +30,8 @@ import org.springframework.lang.Nullable;
*
* @author Juergen Hoeller
* @author Rob Harrop
* @author Stephane Nicoll
* @author Sam Brannen
* @since 21.01.2004
* @param <E> the element type
*/
@@ -54,16 +56,16 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe
/**
* Return a new instance containing an arbitrary number of elements.
* Create a new instance containing an arbitrary number of elements.
* @param elements the elements to be contained in the set
* @param <E> the {@code Set}'s element type
* @return a {@code Set} containing the specified elements
* @return a {@code ManagedSet} containing the specified elements
* @since 5.3.16
*/
@SuppressWarnings("unchecked")
@SafeVarargs
public static <E> ManagedSet<E> of(E... elements) {
ManagedSet<E> set = new ManagedSet<>();
set.addAll(Arrays.asList(elements));
Collections.addAll(set, elements);
return set;
}
@@ -124,7 +124,7 @@ public abstract class AbstractBeanDefinitionParser implements BeanDefinitionPars
/**
* Register the supplied {@link BeanDefinitionHolder bean} with the supplied
* {@link BeanDefinitionRegistry registry}.
* <p>Subclasses can override this method to control whether or not the supplied
* <p>Subclasses can override this method to control whether the supplied
* {@link BeanDefinitionHolder bean} is actually even registered, or to
* register even more beans.
* <p>The default implementation registers the supplied {@link BeanDefinitionHolder bean}
@@ -1362,7 +1362,7 @@ public class BeanDefinitionParserDelegate {
}
/**
* Parse a custom element (outside of the default namespace).
* Parse a custom element (outside the default namespace).
* @param ele the element to parse
* @return the resulting bean definition
*/
@@ -1372,7 +1372,7 @@ public class BeanDefinitionParserDelegate {
}
/**
* Parse a custom element (outside of the default namespace).
* Parse a custom element (outside the default namespace).
* @param ele the element to parse
* @param containingBd the containing bean definition (if any)
* @return the resulting bean definition
@@ -96,7 +96,7 @@ public class DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver
* Create a new {@code DefaultNamespaceHandlerResolver} using the
* supplied mapping file location.
* @param classLoader the {@link ClassLoader} instance used to load mapping resources
* may be {@code null}, in which case the thread context ClassLoader will be used)
* may be {@code null}, in which case the thread context ClassLoader will be used
* @param handlerMappingsLocation the mapping file location
*/
public DefaultNamespaceHandlerResolver(@Nullable ClassLoader classLoader, String handlerMappingsLocation) {
@@ -56,7 +56,7 @@ public class DelegatingEntityResolver implements EntityResolver {
* <p>Configures the {@link PluggableSchemaResolver} with the supplied
* {@link ClassLoader}.
* @param classLoader the ClassLoader to use for loading
* (can be {@code null}) to use the default ClassLoader)
* (can be {@code null} to use the default ClassLoader)
*/
public DelegatingEntityResolver(@Nullable ClassLoader classLoader) {
this.dtdResolver = new BeansDtdResolver();
@@ -80,7 +80,7 @@ public class PluggableSchemaResolver implements EntityResolver {
* Loads the schema URL &rarr; schema file location mappings using the default
* mapping file pattern "META-INF/spring.schemas".
* @param classLoader the ClassLoader to use for loading
* (can be {@code null}) to use the default ClassLoader)
* (can be {@code null} to use the default ClassLoader)
* @see PropertiesLoaderUtils#loadAllProperties(String, ClassLoader)
*/
public PluggableSchemaResolver(@Nullable ClassLoader classLoader) {
@@ -92,7 +92,7 @@ public class PluggableSchemaResolver implements EntityResolver {
* Loads the schema URL &rarr; schema file location mappings using the given
* mapping file pattern.
* @param classLoader the ClassLoader to use for loading
* (can be {@code null}) to use the default ClassLoader)
* (can be {@code null} to use the default ClassLoader)
* @param schemaMappingsLocation the location of the file that defines schema mappings
* (must not be empty)
* @see PropertiesLoaderUtils#loadAllProperties(String, ClassLoader)
@@ -50,7 +50,7 @@ import org.springframework.util.StringUtils;
* the bean that will be considered as a parameter.
*
* <b>Note</b>: This implementation supports only named parameters - there is no
* support for indexes or types. Further more, the names are used as hints by
* support for indexes or types. Furthermore, the names are used as hints by
* the container which, by default, does type introspection.
*
* @author Costin Leau
@@ -184,7 +184,7 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
}
/**
* Set whether or not the XML parser should be XML namespace aware.
* Set whether the XML parser should be XML namespace aware.
* Default is "false".
* <p>This is typically not needed when schema validation is active.
* However, without validation, this has to be switched to "true"
@@ -195,7 +195,7 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
}
/**
* Return whether or not the XML parser should be XML namespace aware.
* Return whether the XML parser should be XML namespace aware.
*/
public boolean isNamespaceAware() {
return this.namespaceAware;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2022 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.
@@ -29,6 +29,7 @@ import org.springframework.util.StringUtils;
* e.g. {@code UTF-8}, {@code ISO-8859-16}, etc.
*
* @author Arjen Poutsma
* @author Sam Brannen
* @since 2.5.4
* @see Charset
*/
@@ -37,7 +38,7 @@ public class CharsetEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (StringUtils.hasText(text)) {
setValue(Charset.forName(text));
setValue(Charset.forName(text.trim()));
}
else {
setValue(null);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2022 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.
@@ -19,11 +19,14 @@ package org.springframework.beans.propertyeditors;
import java.beans.PropertyEditorSupport;
import java.util.Currency;
import org.springframework.util.StringUtils;
/**
* Editor for {@code java.util.Currency}, translating currency codes into Currency
* objects. Exposes the currency code as text representation of a Currency object.
*
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3.0
* @see java.util.Currency
*/
@@ -31,6 +34,9 @@ public class CurrencyEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (StringUtils.hasText(text)) {
text = text.trim();
}
setValue(Currency.getInstance(text));
}
@@ -26,7 +26,7 @@ import org.springframework.util.StringUtils;
* Custom {@link java.beans.PropertyEditor} for String arrays.
*
* <p>Strings must be in CSV format, with a customizable separator.
* By default values in the result are trimmed of whitespace.
* By default, values in the result are trimmed of whitespace.
*
* @author Rod Johnson
* @author Juergen Hoeller
@@ -86,7 +86,7 @@ public class StringArrayPropertyEditor extends PropertyEditorSupport {
* @param emptyArrayAsNull {@code true} if an empty String array
* is to be transformed into {@code null}
* @param trimValues {@code true} if the values in the parsed arrays
* are to be trimmed of whitespace (default is true)
* are to be trimmed of whitespace (default is {@code true})
*/
public StringArrayPropertyEditor(String separator, boolean emptyArrayAsNull, boolean trimValues) {
this(separator, null, emptyArrayAsNull, trimValues);
@@ -114,7 +114,7 @@ public class StringArrayPropertyEditor extends PropertyEditorSupport {
* @param emptyArrayAsNull {@code true} if an empty String array
* is to be transformed into {@code null}
* @param trimValues {@code true} if the values in the parsed arrays
* are to be trimmed of whitespace (default is true)
* are to be trimmed of whitespace (default is {@code true})
*/
public StringArrayPropertyEditor(
String separator, @Nullable String charsToDelete, boolean emptyArrayAsNull, boolean trimValues) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2022 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.springframework.util.StringUtils;
*
* @author Juergen Hoeller
* @author Nicholas Williams
* @author Sam Brannen
* @since 3.0
* @see java.util.TimeZone
* @see ZoneIdEditor
@@ -36,6 +37,9 @@ public class TimeZoneEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (StringUtils.hasText(text)) {
text = text.trim();
}
setValue(StringUtils.parseTimeZoneString(text));
}
@@ -130,7 +130,7 @@ public class URIEditor extends PropertyEditorSupport {
/**
* Create a URI instance for the given user-specified String value.
* <p>The default implementation encodes the value into a RFC-2396 compliant URI.
* <p>The default implementation encodes the value into an RFC-2396 compliant URI.
* @param value the value to convert into a URI instance
* @return the URI instance
* @throws java.net.URISyntaxException if URI conversion failed
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2022 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.
@@ -19,11 +19,14 @@ package org.springframework.beans.propertyeditors;
import java.beans.PropertyEditorSupport;
import java.time.ZoneId;
import org.springframework.util.StringUtils;
/**
* Editor for {@code java.time.ZoneId}, translating zone ID Strings into {@code ZoneId}
* objects. Exposes the {@code TimeZone} ID as a text representation.
*
* @author Nicholas Williams
* @author Sam Brannen
* @since 4.0
* @see java.time.ZoneId
* @see TimeZoneEditor
@@ -32,6 +35,9 @@ public class ZoneIdEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (StringUtils.hasText(text)) {
text = text.trim();
}
setValue(ZoneId.of(text));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2022 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.
@@ -43,6 +43,7 @@ import org.springframework.core.io.ContextResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceEditor;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.WritableResource;
import org.springframework.core.io.support.ResourceArrayPropertyEditor;
import org.springframework.core.io.support.ResourcePatternResolver;
@@ -102,6 +103,7 @@ public class ResourceEditorRegistrar implements PropertyEditorRegistrar {
ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);
doRegisterEditor(registry, Resource.class, baseEditor);
doRegisterEditor(registry, ContextResource.class, baseEditor);
doRegisterEditor(registry, WritableResource.class, baseEditor);
doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2022 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,7 +39,7 @@ inline fun <reified T : Any> ListableBeanFactory.getBeansOfType(includeNonSingle
/**
* Extension for [ListableBeanFactory.getBeanNamesForAnnotation] providing a
* `getBeansOfType<Foo>()` variant.
* `getBeanNamesForAnnotation<Foo>()` variant.
*
* @author Sebastien Deleuze
* @since 5.0
@@ -280,7 +280,7 @@ class BeanUtilsTests {
* {@code Number} can NOT be copied to {@code Integer}.
*/
@Test
void copyPropertiesDoesNotCopyeFromSuperTypeToSubType() {
void copyPropertiesDoesNotCopyFromSuperTypeToSubType() {
NumberHolder numberHolder = new NumberHolder();
numberHolder.setNumber(Integer.valueOf(42));
IntegerHolder integerHolder = new IntegerHolder();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -23,6 +23,9 @@ import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.springframework.beans.testfixture.beans.TestBean;
import org.springframework.core.OverridingClassLoader;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.UrlResource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -105,7 +108,7 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
.satisfies(ex -> assertThat(ex.getPossibleMatches()).containsExactly("age"));
}
@Test // Can't be shared; there is no such thing as a read-only field
@Test // Can't be shared; there is no such thing as a read-only field
void setReadOnlyMapProperty() {
TypedReadOnlyMap map = new TypedReadOnlyMap(Collections.singletonMap("key", new TestBean()));
TypedReadOnlyMapClient target = new TypedReadOnlyMapClient();
@@ -151,18 +154,58 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
}
@Test
void propertyDescriptors() {
void propertyDescriptors() throws Exception {
TestBean target = new TestBean();
target.setSpouse(new TestBean());
BeanWrapper accessor = createAccessor(target);
accessor.setPropertyValue("name", "a");
accessor.setPropertyValue("spouse.name", "b");
assertThat(target.getName()).isEqualTo("a");
assertThat(target.getSpouse().getName()).isEqualTo("b");
assertThat(accessor.getPropertyValue("name")).isEqualTo("a");
assertThat(accessor.getPropertyValue("spouse.name")).isEqualTo("b");
assertThat(accessor.getPropertyDescriptor("name").getPropertyType()).isEqualTo(String.class);
assertThat(accessor.getPropertyDescriptor("spouse.name").getPropertyType()).isEqualTo(String.class);
assertThat(accessor.isReadableProperty("class.package")).isFalse();
assertThat(accessor.isReadableProperty("class.module")).isFalse();
assertThat(accessor.isReadableProperty("class.classLoader")).isFalse();
assertThat(accessor.isReadableProperty("class.name")).isTrue();
assertThat(accessor.isReadableProperty("class.simpleName")).isTrue();
assertThat(accessor.getPropertyValue("class.name")).isEqualTo(TestBean.class.getName());
assertThat(accessor.getPropertyValue("class.simpleName")).isEqualTo(TestBean.class.getSimpleName());
assertThat(accessor.getPropertyDescriptor("class.name").getPropertyType()).isEqualTo(String.class);
assertThat(accessor.getPropertyDescriptor("class.simpleName").getPropertyType()).isEqualTo(String.class);
accessor = createAccessor(new DefaultResourceLoader());
assertThat(accessor.isReadableProperty("class.package")).isFalse();
assertThat(accessor.isReadableProperty("class.module")).isFalse();
assertThat(accessor.isReadableProperty("class.classLoader")).isFalse();
assertThat(accessor.isReadableProperty("class.name")).isTrue();
assertThat(accessor.isReadableProperty("class.simpleName")).isTrue();
assertThat(accessor.isReadableProperty("classLoader")).isTrue();
assertThat(accessor.isWritableProperty("classLoader")).isTrue();
OverridingClassLoader ocl = new OverridingClassLoader(getClass().getClassLoader());
accessor.setPropertyValue("classLoader", ocl);
assertThat(accessor.getPropertyValue("classLoader")).isSameAs(ocl);
accessor = createAccessor(new UrlResource("https://spring.io"));
assertThat(accessor.isReadableProperty("class.package")).isFalse();
assertThat(accessor.isReadableProperty("class.module")).isFalse();
assertThat(accessor.isReadableProperty("class.classLoader")).isFalse();
assertThat(accessor.isReadableProperty("class.name")).isTrue();
assertThat(accessor.isReadableProperty("class.simpleName")).isTrue();
assertThat(accessor.isReadableProperty("URL.protocol")).isTrue();
assertThat(accessor.isReadableProperty("URL.host")).isTrue();
assertThat(accessor.isReadableProperty("URL.port")).isTrue();
assertThat(accessor.isReadableProperty("URL.file")).isTrue();
assertThat(accessor.isReadableProperty("URL.content")).isFalse();
assertThat(accessor.isReadableProperty("inputStream")).isFalse();
assertThat(accessor.isReadableProperty("filename")).isTrue();
assertThat(accessor.isReadableProperty("description")).isTrue();
}
@Test
@@ -26,7 +26,6 @@ import java.security.Principal;
import java.security.PrivilegedAction;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -95,6 +94,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
@@ -178,10 +178,8 @@ class DefaultListableBeanFactoryTests {
registerBeanDefinitions(p);
assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(0);
beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
assertThat(beanNames).hasSize(0);
assertBeanNamesForType(TestBean.class, false, false);
assertThat(lbf.getBeanNamesForAnnotation(SuppressWarnings.class)).isEmpty();
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
@@ -212,10 +210,8 @@ class DefaultListableBeanFactoryTests {
registerBeanDefinitions(p);
assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(0);
beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
assertThat(beanNames).hasSize(0);
assertBeanNamesForType(TestBean.class, false, false);
assertThat(lbf.getBeanNamesForAnnotation(SuppressWarnings.class)).isEmpty();
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
@@ -245,10 +241,8 @@ class DefaultListableBeanFactoryTests {
registerBeanDefinitions(p);
assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(0);
beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
assertThat(beanNames).hasSize(0);
assertBeanNamesForType(TestBean.class, false, false);
assertThat(lbf.getBeanNamesForAnnotation(SuppressWarnings.class)).isEmpty();
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
@@ -278,10 +272,8 @@ class DefaultListableBeanFactoryTests {
registerBeanDefinitions(p);
lbf.preInstantiateSingletons();
assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(1);
assertThat(beanNames[0]).isEqualTo("x1");
assertThat(DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isFalse();
assertBeanNamesForType(TestBean.class, true, false, "x1");
assertThat(lbf.containsSingleton("x1")).isTrue();
assertThat(lbf.containsBean("x1")).isTrue();
assertThat(lbf.containsBean("&x1")).isTrue();
@@ -316,14 +308,10 @@ class DefaultListableBeanFactoryTests {
assertThat(lbf.isTypeMatch("&x2", Object.class)).isTrue();
assertThat(lbf.getType("x2")).isEqualTo(TestBean.class);
assertThat(lbf.getType("&x2")).isEqualTo(DummyFactory.class);
assertThat(lbf.getAliases("x1").length).isEqualTo(1);
assertThat(lbf.getAliases("x1")[0]).isEqualTo("x2");
assertThat(lbf.getAliases("&x1").length).isEqualTo(1);
assertThat(lbf.getAliases("&x1")[0]).isEqualTo("&x2");
assertThat(lbf.getAliases("x2").length).isEqualTo(1);
assertThat(lbf.getAliases("x2")[0]).isEqualTo("x1");
assertThat(lbf.getAliases("&x2").length).isEqualTo(1);
assertThat(lbf.getAliases("&x2")[0]).isEqualTo("&x1");
assertThat(lbf.getAliases("x1")).containsExactly("x2");
assertThat(lbf.getAliases("&x1")).containsExactly("&x2");
assertThat(lbf.getAliases("x2")).containsExactly("x1");
assertThat(lbf.getAliases("&x2")).containsExactly("&x1");
}
@Test
@@ -333,9 +321,7 @@ class DefaultListableBeanFactoryTests {
lbf.registerBeanDefinition("x1", rbd);
TestBeanFactory.initialized = false;
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(1);
assertThat(beanNames[0]).isEqualTo("x1");
assertBeanNamesForType(TestBean.class, true, false, "x1");
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
assertThat(lbf.containsBean("&x1")).isFalse();
@@ -358,9 +344,7 @@ class DefaultListableBeanFactoryTests {
lbf.registerBeanDefinition("x1", rbd);
TestBeanFactory.initialized = false;
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(1);
assertThat(beanNames[0]).isEqualTo("x1");
assertBeanNamesForType(TestBean.class, true, false, "x1");
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
assertThat(lbf.containsBean("&x1")).isFalse();
@@ -385,9 +369,7 @@ class DefaultListableBeanFactoryTests {
lbf.registerBeanDefinition("x1", rbd);
TestBeanFactory.initialized = false;
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(1);
assertThat(beanNames[0]).isEqualTo("x1");
assertBeanNamesForType(TestBean.class, true, false, "x1");
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
assertThat(lbf.containsBean("&x1")).isFalse();
@@ -413,9 +395,7 @@ class DefaultListableBeanFactoryTests {
lbf.registerBeanDefinition("x1", rbd);
TestBeanFactory.initialized = false;
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(1);
assertThat(beanNames[0]).isEqualTo("x1");
assertBeanNamesForType(TestBean.class, true, false, "x1");
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
assertThat(lbf.containsBean("&x1")).isFalse();
@@ -448,14 +428,10 @@ class DefaultListableBeanFactoryTests {
assertThat(lbf.isTypeMatch("&x2", Object.class)).isFalse();
assertThat(lbf.getType("x2")).isEqualTo(TestBean.class);
assertThat(lbf.getType("&x2")).isNull();
assertThat(lbf.getAliases("x1").length).isEqualTo(1);
assertThat(lbf.getAliases("x1")[0]).isEqualTo("x2");
assertThat(lbf.getAliases("&x1").length).isEqualTo(1);
assertThat(lbf.getAliases("&x1")[0]).isEqualTo("&x2");
assertThat(lbf.getAliases("x2").length).isEqualTo(1);
assertThat(lbf.getAliases("x2")[0]).isEqualTo("x1");
assertThat(lbf.getAliases("&x2").length).isEqualTo(1);
assertThat(lbf.getAliases("&x2")[0]).isEqualTo("&x1");
assertThat(lbf.getAliases("x1")).containsExactly("x2");
assertThat(lbf.getAliases("&x1")).containsExactly("&x2");
assertThat(lbf.getAliases("x2")).containsExactly("x1");
assertThat(lbf.getAliases("&x2")).containsExactly("&x1");
}
@Test
@@ -619,8 +595,7 @@ class DefaultListableBeanFactoryTests {
lbf.registerSingleton("string", "A");
TestBean self = (TestBean) lbf.getBean("self");
assertThat(self.getStringArray()).hasSize(1);
assertThat(self.getStringArray()).contains("A");
assertThat(self.getStringArray()).containsExactly("A");
}
@Test
@@ -633,8 +608,7 @@ class DefaultListableBeanFactoryTests {
lbf.registerSingleton("string", "A");
TestBean self = (TestBean) lbf.getBean("self");
assertThat(self.getStringArray()).hasSize(1);
assertThat(self.getStringArray()).contains("A");
assertThat(self.getStringArray()).containsExactly("A");
}
@Test
@@ -666,8 +640,7 @@ class DefaultListableBeanFactoryTests {
.withCauseInstanceOf(NotWritablePropertyException.class)
.satisfies(ex -> {
NotWritablePropertyException cause = (NotWritablePropertyException) ex.getCause();
assertThat(cause.getPossibleMatches()).hasSize(1);
assertThat(cause.getPossibleMatches()[0]).isEqualTo("age");
assertThat(cause.getPossibleMatches()).containsExactly("age");
});
}
@@ -685,7 +658,7 @@ class DefaultListableBeanFactoryTests {
lbf = new DefaultListableBeanFactory();
p = new Properties();
p.setProperty("kerry.(class)", TestBean.class.getName());
p.setProperty("kerry.(scope)", "prototype");
p.setProperty("kerry.(scope)", BeanDefinition.SCOPE_PROTOTYPE);
p.setProperty("kerry.age", "35");
registerBeanDefinitions(p);
kerry1 = (TestBean) lbf.getBean("kerry");
@@ -1145,7 +1118,7 @@ class DefaultListableBeanFactoryTests {
assertThat(lbf.containsBean("singletonObject")).isTrue();
assertThat(lbf.isSingleton("singletonObject")).isTrue();
assertThat(lbf.getType("singletonObject")).isEqualTo(TestBean.class);
assertThat(lbf.getAliases("singletonObject").length).isEqualTo(0);
assertThat(lbf.getAliases("singletonObject")).isEmpty();
DependenciesBean test = (DependenciesBean) lbf.getBean("test");
assertThat(lbf.getBean("singletonObject")).isEqualTo(singletonObject);
assertThat(test.getSpouse()).isEqualTo(singletonObject);
@@ -1791,12 +1764,12 @@ class DefaultListableBeanFactoryTests {
assertThat(bean.beanName).isEqualTo("bd1");
assertThat(bean.spouseAge).isEqualTo(42);
assertThat(lbf.getBeanNamesForType(ConstructorDependency.class).length).isEqualTo(1);
assertThat(lbf.getBeanNamesForType(ConstructorDependencyFactoryBean.class).length).isEqualTo(1);
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class)).length).isEqualTo(1);
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, String.class)).length).isEqualTo(0);
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class), true, true).length).isEqualTo(1);
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, String.class), true, true).length).isEqualTo(0);
assertThat(lbf.getBeanNamesForType(ConstructorDependency.class)).hasSize(1);
assertThat(lbf.getBeanNamesForType(ConstructorDependencyFactoryBean.class)).hasSize(1);
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class))).hasSize(1);
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, String.class))).isEmpty();
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class), true, true)).hasSize(1);
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, String.class), true, true)).isEmpty();
}
private RootBeanDefinition createConstructorDependencyBeanDefinition(int age) {
@@ -1861,46 +1834,45 @@ class DefaultListableBeanFactoryTests {
@Test
void getBeanNamesForTypeBeforeFactoryBeanCreation() {
FactoryBeanThatShouldntBeCalled.instantiated = false;
lbf.registerBeanDefinition("factoryBean", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class));
assertThat(lbf.containsSingleton("factoryBean")).isFalse();
assertThat(FactoryBeanThatShouldntBeCalled.instantiated).isFalse();
String[] beanNames = lbf.getBeanNamesForType(Runnable.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");
beanNames = lbf.getBeanNamesForType(Callable.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");
beanNames = lbf.getBeanNamesForType(RepositoryFactoryInformation.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");
beanNames = lbf.getBeanNamesForType(FactoryBean.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");
assertBeanNamesForType(Runnable.class, false, false, "&factoryBean");
assertBeanNamesForType(Callable.class, false, false, "&factoryBean");
assertBeanNamesForType(RepositoryFactoryInformation.class, false, false, "&factoryBean");
assertBeanNamesForType(FactoryBean.class, false, false, "&factoryBean");
}
@Test
void getBeanNamesForTypeAfterFactoryBeanCreation() {
FactoryBeanThatShouldntBeCalled.instantiated = false;
lbf.registerBeanDefinition("factoryBean", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class));
lbf.getBean("&factoryBean");
assertThat(FactoryBeanThatShouldntBeCalled.instantiated).isTrue();
assertThat(lbf.containsSingleton("factoryBean")).isTrue();
String[] beanNames = lbf.getBeanNamesForType(Runnable.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");
assertBeanNamesForType(Runnable.class, false, false, "&factoryBean");
assertBeanNamesForType(Callable.class, false, false, "&factoryBean");
assertBeanNamesForType(RepositoryFactoryInformation.class, false, false, "&factoryBean");
assertBeanNamesForType(FactoryBean.class, false, false, "&factoryBean");
}
beanNames = lbf.getBeanNamesForType(Callable.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");
@Test // gh-28616
void getBeanNamesForTypeWithPrototypeScopedFactoryBean() {
FactoryBeanThatShouldntBeCalled.instantiated = false;
RootBeanDefinition beanDefinition = new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class);
beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
lbf.registerBeanDefinition("factoryBean", beanDefinition);
assertThat(FactoryBeanThatShouldntBeCalled.instantiated).isFalse();
assertThat(lbf.containsSingleton("factoryBean")).isFalse();
beanNames = lbf.getBeanNamesForType(RepositoryFactoryInformation.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");
beanNames = lbf.getBeanNamesForType(FactoryBean.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");
// We should not find any beans of the following types if the FactoryBean itself is prototype-scoped.
assertBeanNamesForType(Runnable.class, false, false);
assertBeanNamesForType(Callable.class, false, false);
assertBeanNamesForType(RepositoryFactoryInformation.class, false, false);
assertBeanNamesForType(FactoryBean.class, false, false);
}
/**
@@ -2010,6 +1982,21 @@ class DefaultListableBeanFactoryTests {
assertThat(bean.getSpouse()).isEqualTo(lbf.getBean("spouse"));
}
@Test
void beanProviderWithParentBeanFactoryReuseOrder() {
DefaultListableBeanFactory parentBf = new DefaultListableBeanFactory();
parentBf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
parentBf.registerBeanDefinition("regular", new RootBeanDefinition(TestBean.class));
parentBf.registerBeanDefinition("test", new RootBeanDefinition(HighPriorityTestBean.class));
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
lbf.setParentBeanFactory(parentBf);
lbf.registerBeanDefinition("low", new RootBeanDefinition(LowPriorityTestBean.class));
List<Class<?>> orderedTypes = lbf.getBeanProvider(TestBean.class).orderedStream()
.map(Object::getClass).collect(Collectors.toList());
assertThat(orderedTypes).containsExactly(
HighPriorityTestBean.class, LowPriorityTestBean.class, TestBean.class);
}
@Test
void autowireExistingBeanByName() {
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
@@ -2165,8 +2152,7 @@ class DefaultListableBeanFactoryTests {
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyBean.class);
bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
lbf.registerBeanDefinition("test", bd);
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(
lbf::preInstantiateSingletons);
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(lbf::preInstantiateSingletons);
}
@Test
@@ -2174,8 +2160,7 @@ class DefaultListableBeanFactoryTests {
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
lbf.registerBeanDefinition("test", bd);
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(
lbf::preInstantiateSingletons);
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(lbf::preInstantiateSingletons);
}
@Test
@@ -2183,8 +2168,7 @@ class DefaultListableBeanFactoryTests {
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
lbf.registerBeanDefinition("test", bd);
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() ->
lbf.getBeansOfType(String.class));
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() -> lbf.getBeansOfType(String.class));
}
@Test
@@ -2211,8 +2195,7 @@ class DefaultListableBeanFactoryTests {
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyWithClassResolution.class);
bd.getConstructorArgumentValues().addGenericArgumentValue("java.lang.Strin");
lbf.registerBeanDefinition("test", bd);
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(
lbf::preInstantiateSingletons);
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(lbf::preInstantiateSingletons);
}
@Test
@@ -2236,7 +2219,13 @@ class DefaultListableBeanFactoryTests {
@Test
void prototypeFactoryBeanNotEagerlyCalled() {
lbf.registerBeanDefinition("test", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class));
lbf.preInstantiateSingletons();
assertThatNoException().isThrownBy(lbf::preInstantiateSingletons);
}
@Test
void prototypeFactoryBeanNotEagerlyCalledInCaseOfBeanClassName() {
lbf.registerBeanDefinition("test", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class.getName(), null, null));
assertThatNoException().isThrownBy(lbf::preInstantiateSingletons);
}
@Test
@@ -2276,13 +2265,6 @@ class DefaultListableBeanFactoryTests {
assertThat(factory.initialized).isTrue();
}
@Test
void prototypeFactoryBeanNotEagerlyCalledInCaseOfBeanClassName() {
lbf.registerBeanDefinition("test",
new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class.getName(), null, null));
lbf.preInstantiateSingletons();
}
@Test
void prototypeStringCreatedRepeatedly() {
RootBeanDefinition stringDef = new RootBeanDefinition(String.class);
@@ -2462,10 +2444,7 @@ class DefaultListableBeanFactoryTests {
lbf.registerBeanDefinition("fmWithArgs", factoryMethodDefinitionWithArgs);
assertThat(lbf.getBeanDefinitionCount()).isEqualTo(4);
List<String> tbNames = Arrays.asList(lbf.getBeanNamesForType(TestBean.class));
assertThat(tbNames.contains("fmWithProperties")).isTrue();
assertThat(tbNames.contains("fmWithArgs")).isTrue();
assertThat(tbNames.size()).isEqualTo(2);
assertBeanNamesForType(TestBean.class, true, true, "fmWithProperties", "fmWithArgs");
TestBean tb = (TestBean) lbf.getBean("fmWithProperties");
TestBean second = (TestBean) lbf.getBean("fmWithProperties");
@@ -2669,6 +2648,19 @@ class DefaultListableBeanFactoryTests {
return (new org.springframework.beans.factory.support.PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p, prefix);
}
private void assertBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit, String... names) {
if (names.length == 0) {
assertThat(lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit))
.as("bean names for type " + type.getName())
.isEmpty();
}
else {
assertThat(lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit))
.as("bean names for type " + type.getName())
.containsExactly(names);
}
}
public static class NoDependencies {
@@ -2859,6 +2851,12 @@ class DefaultListableBeanFactoryTests {
public static class FactoryBeanThatShouldntBeCalled<T extends Repository<S, ID>, S, ID extends Serializable>
extends RepositoryFactoryBeanSupport<T, S, ID> implements Runnable, Callable<T> {
static boolean instantiated = false;
{
instantiated = true;
}
@Override
public T getObject() {
throw new IllegalStateException();
@@ -43,7 +43,7 @@ public class MethodInvokingFactoryBeanTests {
@Test
public void testParameterValidation() throws Exception {
// assert that only static OR non static are set, but not both or none
// assert that only static OR non-static are set, but not both or none
MethodInvokingFactoryBean mcfb = new MethodInvokingFactoryBean();
assertThatIllegalArgumentException().isThrownBy(mcfb::afterPropertiesSet);
@@ -278,19 +278,19 @@ public class ServiceLocatorFactoryBeanTests {
}
public static interface TestServiceLocator {
public interface TestServiceLocator {
TestService getTestService();
}
public static interface TestServiceLocator2 {
public interface TestServiceLocator2 {
TestService getTestService(String id) throws CustomServiceLocatorException2;
}
public static interface TestServiceLocator3 {
public interface TestServiceLocator3 {
TestService getTestService();
@@ -302,13 +302,13 @@ public class ServiceLocatorFactoryBeanTests {
}
public static interface TestService2Locator {
public interface TestService2Locator {
TestService2 getTestService() throws CustomServiceLocatorException3;
}
public static interface ServiceLocatorInterfaceWithExtraNonCompliantMethod {
public interface ServiceLocatorInterfaceWithExtraNonCompliantMethod {
TestService2 getTestService();
@@ -25,61 +25,61 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
* Unit tests for {@link ManagedList}.
*
* @author Rick Evans
* @author Juergen Hoeller
* @author Sam Brannen
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ManagedListTests {
class ManagedListTests {
@Test
public void mergeSunnyDay() {
void mergeSunnyDay() {
ManagedList parent = ManagedList.of("one", "two");
ManagedList child = ManagedList.of("three");
child.setMergeEnabled(true);
List mergedList = child.merge(parent);
assertThat(mergedList.size()).as("merge() obviously did not work.").isEqualTo(3);
assertThat(mergedList).as("merge() obviously did not work.").containsExactly("one", "two", "three");
}
@Test
public void mergeWithNullParent() {
void mergeWithNullParent() {
ManagedList child = ManagedList.of("one");
child.setMergeEnabled(true);
assertThat(child.merge(null)).isSameAs(child);
}
@Test
public void mergeNotAllowedWhenMergeNotEnabled() {
void mergeNotAllowedWhenMergeNotEnabled() {
ManagedList child = new ManagedList();
assertThatIllegalStateException().isThrownBy(() ->
child.merge(null));
assertThatIllegalStateException().isThrownBy(() -> child.merge(null));
}
@Test
public void mergeWithNonCompatibleParentType() {
void mergeWithIncompatibleParentType() {
ManagedList child = ManagedList.of("one");
child.setMergeEnabled(true);
assertThatIllegalArgumentException().isThrownBy(() ->
child.merge("hello"));
assertThatIllegalArgumentException().isThrownBy(() -> child.merge("hello"));
}
@Test
public void mergeEmptyChild() {
void mergeEmptyChild() {
ManagedList parent = ManagedList.of("one", "two");
ManagedList child = new ManagedList();
child.setMergeEnabled(true);
List mergedList = child.merge(parent);
assertThat(mergedList.size()).as("merge() obviously did not work.").isEqualTo(2);
assertThat(mergedList).as("merge() obviously did not work.").containsExactly("one", "two");
}
@Test
public void mergeChildValuesOverrideTheParents() {
void mergedChildValuesDoNotOverrideTheParents() {
// doesn't make much sense in the context of a list...
ManagedList parent = ManagedList.of("one", "two");
ManagedList child = ManagedList.of("one");
child.setMergeEnabled(true);
List mergedList = child.merge(parent);
assertThat(mergedList.size()).as("merge() obviously did not work.").isEqualTo(3);
assertThat(mergedList).as("merge() obviously did not work.").containsExactly("one", "two", "one");
}
}

Some files were not shown because too many files have changed in this diff Show More