Compare commits

...

603 Commits

Author SHA1 Message Date
Spring Builds 4fe1eaddec Release v6.0.0-M3 2022-03-17 09:35:54 +00:00
Sam Brannen fc8f31ccfb Deprecate "enclosing classes" search strategy for MergedAnnotations
This commit deprecates the TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search
strategy for MergedAnnotations in 6.0 M3, allowing consumers of 6.0
milestones and release candidates to provide feedback before
potentially completely removing the search strategy or providing an
alternate mechanism for achieving the same goal prior to 6.0 GA.

Closes gh-28079
See gh-28080
2022-03-16 19:34:38 +01:00
Mark Paluch a3781a45d6 Align with R2DBC 0.9 API changes
Adopt to R2DBC Parameter type, deprecate our own one in favor of the R2DBC type.
Add support for extensible transaction definitions and support to consume Readable and result segments.
Return Long instead of Integer in DatabaseClient update in preparation for R2DBC 1.0 changes.
2022-03-16 19:27:14 +01:00
Sam Brannen fd34533a3e Merge branch '5.3.x' 2022-03-16 19:24:37 +01:00
Stephane Nicoll 84568e8dbc Merge branch '5.3.x' 2022-03-16 18:16:52 +01:00
Sébastien Deleuze 77e0100f42 Implement GraalVM native JSON configuration generation
This commit implements 4 package private Json serializers
for JavaSerializationHints, ProxyHints, ReflectionHints
and ResourceHints to serialize GraalVM native JSON configuration
as documented in
https://www.graalvm.org/22.0/reference-manual/native-image/BuildConfiguration/.

It exposes the related functionality via
NativeConfigurationGenerator which allows to generate the
relevant files on the filesystem via the
FileNativeConfigurationGenerator implementation.

The generated *-config.json files have been validated working
with GraalVM 22.0.

Closes gh-27991
2022-03-16 16:15:58 +01:00
Sam Brannen bb9cf7cce1 Merge branch '5.3.x' 2022-03-16 15:29:22 +01:00
Sam Brannen ae51ca9bca Revert "Remove deprecated "enclosing classes" search strategy for MergedAnnotations"
This reverts commit 819d4256b7.

See gh-28080
2022-03-16 15:18:34 +01:00
Sam Brannen 9764f0e59b Merge branch '5.3.x'
# Conflicts:
#	spring-test/src/test/java/org/springframework/mock/http/server/reactive/MockServerHttpRequestTests.java
#	spring-web/src/test/java/org/springframework/http/server/reactive/HeadersAdaptersTests.java
#	spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java
#	spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java
#	spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/SseIntegrationTests.java
#	spring-webmvc/src/test/java/org/springframework/web/servlet/handler/MappedInterceptorTests.java
#	spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HandlerMethodAnnotationDetectionTests.java
#	spring-websocket/src/test/java/org/springframework/web/socket/AbstractWebSocketIntegrationTests.java
2022-03-16 15:07:53 +01:00
Juergen Hoeller c3aed75b92 Merge branch '5.3.x'
# Conflicts:
#	build.gradle
2022-03-16 11:24:24 +01:00
Juergen Hoeller 0a1ce75c7c Upgrade to Groovy 4.0.1, Log4J 2.17.2, SLF4J 1.7.36, Netty 4.1.75, SmallRye Mutiny 1.4, Jetty Reactive HttpClient 3.0.5, Hibernate ORM 5.6.6, Hibernate Validator 7.0.4, Mockito 4.4, HtmlUnit 2.59 2022-03-16 10:32:51 +01:00
rstoyanchev e7b97f5be7 Merge branch '5.3.x' into main 2022-03-16 09:27:43 +00:00
Stephane Nicoll 03179aa397 Merge pull request #28057 from philwebb
* pr/28057:
  Polish contribution
  Provide more control over factory failure handling
  Allow flexible constructor arguments in factory implementations

Closes gh-28057
2022-03-15 20:48:32 +01:00
Stephane Nicoll da45bd2dfd Polish contribution
See gh-28057
2022-03-15 20:19:46 +01:00
Phillip Webb 12244b2e51 Provide more control over factory failure handling
Add an additional `FactoryInstantiationFailureHandler` strategy
interface to `SpringFactoriesLoader` to allows instantiation
failures to be handled on a per-factory bases.

For example, to log trace messages for only factories that can't
be created the following can be used:

	FactoryInstantiationFailureHandler.logging(logger);

If no `FactoryInstantiationFailureHandler` instance is supplied
then `FactoryInstantiationFailureHandler.throwing()` is used
which provides back-compatible behavior by throwing an
`IllegalArgumentException`.

See gh-28057

Co-authored-by: Madhura Bhave <bhavem@vmware.com>
Co-authored-by: Andy Wilkinson <wilkinsona@vmware.com>
2022-03-15 20:19:46 +01:00
Phillip Webb 0b716c4f90 Allow flexible constructor arguments in factory implementations
Update `SpringFactoriesLoader` so that factory implementation classes
can have a constructor with arguments that are resolved dynamically.

Arguments are resolved using a `ArgumentResolver` interface that is
passed to the `loadFactories` method. This strategy interface is
intentionally simple and only allows resolution based on the argument
type. A number of convenience methods are provided to allow resolvers
to be built. For example:

	ArgumentResolver.of(String.class, "tests")
			.and(Integer.class, 123);

Factory implementation classes must have a non-ambiguous constructor
in order to be instantiated. The `SpringFactoriesLoader` uses the same
algorithm as `BeanUtils.getResolvableConstructor`.

See gh-28057

Co-authored-by: Madhura Bhave <bhavem@vmware.com>
Co-authored-by: Andy Wilkinson <wilkinsona@vmware.com>
2022-03-15 20:19:46 +01:00
Sébastien Deleuze ae1956cac7 Merge branch '5.3.x' 2022-03-15 18:35:59 +01:00
Sam Brannen 1392b0f557 Merge branch '5.3.x' 2022-03-15 17:13:10 +01:00
Sam Brannen 4db2f8ea1b Remove obsolete Nashorn-based scripting tests
Since the Nashorn JavaScript engine was removed in Java 15, these tests
will never be run on a Java 17+ JDK which is required as of Spring
Framework 6.0.

See gh-27919
2022-03-15 16:33:52 +01:00
Stephane Nicoll e9655e8a7b Merge branch '5.3.x' 2022-03-15 16:04:38 +01:00
Sam Brannen 5598f99816 Merge branch '5.3.x' 2022-03-14 20:27:05 +01:00
Sam Brannen 92d9aee3a2 Polish TestSocketUtils 2022-03-14 15:11:04 +01:00
Sam Brannen 389747f91c Make TestSocketUtils abstract 2022-03-13 15:58:53 +01:00
Sam Brannen 542b6427c3 Revise documentation for TestSocketUtils 2022-03-13 15:54:23 +01:00
Sam Brannen 2ab871fbc3 Merge branch '5.3.x' 2022-03-12 18:16:26 +01:00
Sam Brannen c249b578b5 Merge branch '5.3.x' 2022-03-12 16:05:39 +01:00
Sam Brannen 2858c1efb5 Merge branch '5.3.x' 2022-03-12 14:04:29 +01:00
Stephane Nicoll 672555a568 Add support of init and destroy methods
This commit updates InitDestroyBeanPostProcessor so that it contributes
init or destroy method names to the `RootBeanDefinition`. This is then
used by the generator to provide these methods to the optimized AOT
context.

Invocation of those init methods still happen using reflection so
dedicated hints are contributed for them.

Closes gh-28151
2022-03-12 13:35:56 +01:00
Stephane Nicoll 1b7892c559 Merge pull request #28171 from izeye
* pr/28171:
  Add Javadoc since for GenericApplicationContext.refreshForAotProcessing()

Closes gh-28171
2022-03-12 11:42:49 +01:00
izeye 2a9a1f1c3a Add Javadoc since for GenericApplicationContext.refreshForAotProcessing()
See gh-28171
2022-03-12 11:42:36 +01:00
Stephane Nicoll 7be6816129 Merge branch '5.3.x' 2022-03-11 16:22:18 +01:00
Arjen Poutsma 66d758d677 Downgrade Tomcat to 10.0.14
This commit downgrades Tomcat from 10.0.17 to 10.0.14. Later versions
will result in timeouts in MultipartIntegrationTests.
2022-03-11 12:53:17 +01:00
Arjen Poutsma 5abaf20a74 Merge branch '5.3.x' 2022-03-11 12:22:39 +01:00
Sam Brannen 0e7c7b444c Merge branch '5.3.x' 2022-03-10 19:28:51 +01:00
Stephane Nicoll 1742e121e7 Update bean registration contribution tests to use TestCompiler 2022-03-10 16:06:52 +01:00
Stephane Nicoll 93a2651417 Make sure method injection handles ambiguous signatures
This commit updates InjectionGenerator to request a resolved attribute
with a dedicated type if multiple methods with the same name and the
same number of arguments exist. This was previously done already for
constructors and this commit harmonizes the algorithms to methods as
well

Closes gh-28154
2022-03-10 15:34:53 +01:00
Arjen Poutsma f3181dc583 Upgrade to Tomcat 10.0.17
This commit upgrades to Tomcat 10.0.17, hopefully fixing multipart
integration tests as a result.
2022-03-10 14:43:33 +01:00
Stephane Nicoll a0061b7fb9 Remove cast on AbstractFactoryBean
Closes gh-28153
2022-03-10 11:50:24 +01:00
Stephane Nicoll 4184294835 Merge branch '5.3.x' 2022-03-10 10:10:57 +01:00
Stephane Nicoll 67b7c16bc0 Fix visibility of DefaultSockJsSchedulerContainer
Closes gh-28146
2022-03-09 16:38:10 +01:00
Stephane Nicoll 9809752c3c Stop generating unnecessary reference to field type
This commit updates the generator to stop specifying a field type when
reflection is necessary, or when a reference to a field should be
retrieved as its name alone suffices.

This could trigger package protected issues if the field type is not
public.

See gh-28047
2022-03-09 11:17:21 +01:00
Stephane Nicoll e873715737 Fix detection of protected generic parameter
This commit fixes the algorithm used to analyze a generic parameter. If
a type in the generic signature is protected, the type is return rather
than the full signature. This makes sure that the appropriate package
is used. Previously, it would have incorrectly used the type of the
raw class.

Using a generic type for such a use case is wrong, and ProtectedElement
has been updated to expose a `Class` rather than a `ResolvableType`.

See gh-28030
2022-03-09 11:17:21 +01:00
Stephane Nicoll 9b07457d06 Introduce ApplicationContextAotGenerator
This commit introduces a way to process a GenericApplicationContext
ahead of time. Components that can contribute in that phase are
invoked, and their contributions are recorded in the
GeneratedTypeContext.

This commit also expands BeanFactoryContribution so that it can exclude
bean definitions that are no longer required.

Closes gh-28150
2022-03-09 11:17:21 +01:00
Stephane Nicoll 30cd14d61d Add module to support testing of generated code
Closes gh-28120
2022-03-09 11:17:21 +01:00
Stephane Nicoll b5695b9248 Add support for refreshing a GenericApplicationContext for AOT
This commit adds a way to refresh a GenericApplicationContext for ahead
of time processing: refreshForAotProcessing() processes the bean factory
up to a point where it is about to create bean instances.

MergedBeanDefinitionPostProcessor implementations are the only bean
post processors that are invoked during this phase.

Closes gh-28065
2022-03-09 11:17:21 +01:00
Stephane Nicoll 7255a8b48e Polish "Add module to support testing of generated code"
See gh-28120

Co-authored-by: Andy Wilkinson <wilkinsona@vmware.com>
2022-03-09 11:17:21 +01:00
Stephane Nicoll 9ba927215e Add support for ImportAware callback
This commit adds a way for a BeanFactoryPostProcessor to participate to
AOT optimizations by contributing code that replaces its runtime
behaviour.

ConfigurationClassPostProcessor does implement this new interface and
computes a mapping of the ImportAware configuration classes. The mapping
is generated for latter reuse by ImportAwareAotBeanPostProcessor.

Closes gh-2811
2022-03-09 11:17:21 +01:00
Phillip Webb 653dc5951d Add module to support testing of generated code
Add a new unpublished `spring-core-test` module to support testing of
generated code. The module include a `TestCompiler` class which can be
used to dynamically compile generated Java code. It also include an
AssertJ friendly `SourceFile` class which uses qdox to provide targeted
assertions on specific parts of a generated source file.

See gh-28120
2022-03-09 11:17:21 +01:00
Stephane Nicoll ec6a19fc6b Add BeanFactoryContribution for bean registrations
This commits adds an implementation that takes care of contributing
code for each bean definition in the bean factory, invoking
BeanRegistrationContributionProvider to determine the best candidate to
use.

Closes gh-28088
2022-03-09 11:17:21 +01:00
Stephane Nicoll 5bc701d4fe Introduce BeanFactoryContribution
This commit introduces an infrastructure to contribute generated code
ahead of time to initialize a BeanFactory. Code and hints can be
contributed to a BeanFactorInitialization, with the ability to write to
other packages if necessary.

An implementation of that new interface that registers a BeanDefinition
is also included in this commit. It delegates to a
BeanInstantiationGenerator for geenerating the instance supplier that
creates the bean instance.

For corner cases, a BeanRegistrationContributionProvider can be
implemented. It allows to return a custom BeanFactoryContribution for
a particualr bean definition. This usually uses the default
implementation with a custom instance supplier.

Note that this commit adds an temporary executable resolution that is
meant to be replaced by the use of ConstructorResolver

See gh-28088
2022-03-09 11:17:21 +01:00
Stephane Nicoll cc57b55c61 Expose a way to resolved a merged inner bean definition
This commit extracts the logic of resolving a merged bean definition for
an inner bean to a public method so that other components can reuse it.

Closes gh-28093
2022-03-09 11:17:21 +01:00
Stephane Nicoll fd191d165b Add GeneratedType infrastructure
This commit adds an infrastructure for code that generate types with the
need to write to another package if privileged access is required. An
abstraction around types where methods can be easily added is also
available as part of this commit.

Closes gh-28149
2022-03-09 11:17:21 +01:00
Stephane Nicoll 14b147ce70 Add TypeReference implementation for generated code
This commit adds a TypeReference implementation that is suitable for
creating a reference to generated code.

Closes gh-28148
2022-03-09 11:17:21 +01:00
Stephane Nicoll c541bde513 Simplify the generation of inner bean definitions
See gh-28047
2022-03-09 11:17:21 +01:00
Stephane Nicoll 97986b368a Harmonize use of generate
This commit harmonizes the use of the "generate" keyword for anything
related to code generation. Previously, there was a mix of "generate"
and "write."

See gh-28047
2022-03-09 11:17:21 +01:00
Stephane Nicoll ea19b92deb Clarify the scope of AotContributingBeanPostProcessor
This commit updates AotContributingBeanPostProcessor so that it
explicitly extends from PriorityOrdered. This makes it more apparent
that AOT contributing bean post processors are meant to be invoked
early with the regular runtime, and shouldn't be post-processed
themselves.

See gh-28047
2022-03-09 11:17:20 +01:00
Stephane Nicoll 20b17f02a2 Rename BeanInstantiationContributor to Contribution
This commit polishes the contribution model where an AOT contributing
bean post processor can return a contribution, rather than a
contributor. This makes it easier to return `null` if no contribution
can be produced now that it is named this way.

See gh-28047
2022-03-09 11:17:20 +01:00
Stephane Nicoll 572d017370 Add missing package-info
See gh-28047
2022-03-09 11:17:20 +01:00
Sam Brannen 2c3407b0e5 Merge branch '5.3.x' 2022-03-09 11:08:36 +01:00
Arjen Poutsma 1be3eecb2a Replace KotlinBodySpec with extensions function
Prior to this commit, the ResponseSpec::expectBody extension function
returned a special KotlinBodySpec, due to
https://youtrack.jetbrains.com/issue/KT-5464.

Now that KT-5464 has been fixed in Kotlin 1.6, we have no need for
KotlinBodySpec, so this commit replaces it with a extension function
that returns the Java BodySpec.

Closes gh-28144
2022-03-08 16:24:03 +01:00
Sam Brannen 5119aafe4f Merge branch '5.3.x' 2022-03-06 17:52:21 +01:00
Sam Brannen f7d49e3957 Merge branch '5.3.x' 2022-03-05 14:54:19 +01:00
Sam Brannen c1033dbfb3 Support type-safe transaction rollback rules
Prior to this commit, there was no way to configure type-safe rollback
rules for transactions.

Even though a rollback rule could be defined using a Class reference
via the `rollbackFor` and `noRollbackFor` attributes in @Transactional,
those Class references got converted to Strings (as the fully qualified
class names of the exception types) in RollbackRuleAttribute which then
applied a pattern-based matching algorithm as if the Class references
had been supplied as Strings/patterns to begin with, thereby losing the
type information.

Pattern-based rollback rules suffer from the following three categories
of unintentional matches.

- identically named exceptions in different packages when the pattern
  does not include the package name -- for example,
  example.client.WebException and example.server.WebException both
  match against a "WebException" pattern.

- similarly named exceptions in the same package when a given exception
  name starts with the name of another exception -- for example,
  example.BusinessException and example.BusinessExceptionWithDetails
  both match against an "example.BusinessException" pattern.

- nested exceptions when an exception type is declared in another
  exception -- for example, example.BusinessException and
  example.BusinessException$NestedException both match against an
  "example.BusinessException" pattern.

This commit prevents the latter two categories of unintentional matches
for rollback rules defined using a Class reference by storing the
exceptionType in RollbackRuleAttribute and using that type in the
implementation of RollbackRuleAttribute.getDepth(Class, int), resulting
in type-safe rollback rules whenever the `rollbackFor` and
`noRollbackFor` attributes in `@Transactional` are used.

Note that the first category of unintentional matches never applied to
rollback rules created from a Class reference since the fully qualified
name of a Class reference always includes the package name.

Closes gh-28098
2022-03-04 19:33:39 +01:00
Sam Brannen 9cb4783296 Merge branch '5.3.x'
# Conflicts:
#	spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java
#	spring-tx/src/main/java/org/springframework/transaction/interceptor/RollbackRuleAttribute.java
2022-03-04 16:51:26 +01:00
Sam Brannen 68757073b0 Merge branch '5.3.x' 2022-03-02 17:29:26 +01:00
Sam Brannen 14ae522172 Merge branch '5.3.x' 2022-03-01 19:10:54 +01:00
Sam Brannen 66e9095ee9 Fix links and tests broken during merge
See gh-28083
2022-03-01 17:03:59 +01:00
Sam Brannen 466dd825ac Merge branch '5.3.x'
# Conflicts:
#	spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java
#	spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
#	spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java
#	spring-context/src/test/java/org/springframework/context/annotation/Spr3775InitDestroyLifecycleTests.java
2022-03-01 16:48:24 +01:00
Sam Brannen 27ee9cdcde Merge branch '5.3.x' 2022-02-28 17:18:32 +01:00
Brian Clozel c9795597c8 Merge branch '5.3.x' 2022-02-28 16:39:55 +01:00
Brian Clozel 9340e9b716 Upgrade to Kotlin 1.6.20-RC 2022-02-28 15:56:14 +01:00
rstoyanchev c03def79d4 Fix test failures
See gh-27052
2022-02-28 14:17:04 +00:00
rstoyanchev b045e5baef Tests for ErrorResponse hierarchy to verify the output
See gh-27052
2022-02-28 13:40:05 +00:00
rstoyanchev 679432ece6 DefaultHandlerExceptionResolver supports ErrorResponse
DefaultHandlerExceptionResolver now supports ErrorResponse exceptions
and can map them to HTTP status and headers of the response. This
includes not only exceptions from spring-web,  but also any other
exception that implements ErrorResponse.

ResponseEntityExceptionHandler is updated along the same lines, now
also handling any ErrorResponseException. It can be used it for
RFC 7807 support for Spring MVC's own exceptions.

See gh-27052
2022-02-28 13:40:05 +00:00
rstoyanchev 76be6373a8 ErrorResponse support in Spring MVC exception hierarchy
All Spring MVC exceptions from spring-web, now implement ErrorResponse
and expose HTTP error response information, including an RFC 7807 body.

See gh-27052
2022-02-28 13:40:05 +00:00
rstoyanchev 3efedef161 Add ErrorResponse and ErrorResponseException
ErrorResponse represents a complete error response with status, headers,
and an  RFC 7807 ProblemDetail body.

ErrorResponseException implements ErrorResponse and is usable on its
own or as a base class. ResponseStatusException extends
ErrorResponseException and now also supports RFC 7807 and so does its
sub-hierarchy.

ErrorResponse can be returned from `@ExceptionHandler` methods and is
mapped to ResponseEntity.

See gh-27052
2022-02-28 13:40:05 +00:00
rstoyanchev 714d451260 Add ProblemDetail and @ExceptionHandler support
ProblemDetail is a representation of an RFC 7807 "problem", and this
commits adds support for it in Spring MVC and WebFlux as a return value
from `@ExceptionHandler` methods, optionally wrapped with
ResponseEntity for headers.

See gh-27052
2022-02-28 13:40:05 +00:00
Arjen Poutsma 65394b00ea Merge branch '5.3.x' 2022-02-24 14:50:18 +01:00
Stephane Nicoll 5e75f6e009 Merge branch '5.3.x' 2022-02-24 10:55:29 +01:00
Stephane Nicoll 33004a9efd Merge pull request #28100 from izeye
* pr/28100:
  Fix library name for JavaPoet in src/docs/dist/license.txt

Closes gh-28100
2022-02-24 10:52:21 +01:00
izeye a28b49ac27 Fix library name for JavaPoet in src/docs/dist/license.txt
This commit also updates Objenesis version in the file to align with the
version that Spring Framework is using.

See gh-28100
2022-02-24 10:51:54 +01:00
Stephane Nicoll b4eb895927 Polish naming
Co-authored-by: Andy Wilkinson <wilkinsona@vmware.com>
2022-02-22 16:07:52 +01:00
Sam Brannen e85001f332 Clean up warnings in test fixture 2022-02-19 17:32:15 +01:00
Sam Brannen 819d4256b7 Remove deprecated "enclosing classes" search strategy for MergedAnnotations
Closes gh-28080
2022-02-19 17:25:50 +01:00
Sam Brannen ad3095f197 Merge branch '5.3.x' 2022-02-19 17:02:02 +01:00
Sam Brannen be8224a590 Polish contribution
See gh-27818
2022-02-19 16:04:55 +01:00
Guirong Hu 01214b3473 Allow @Async qualifier to be declared with a placeholder or SpEL expression
Closes gh-27818
2022-02-19 15:09:40 +01:00
Sam Brannen 6a73d2655f Polishing 2022-02-19 14:59:54 +01:00
Sam Brannen 8c6d59aaaf Polish contribution
See gh-28014
2022-02-19 14:43:26 +01:00
a.yazychyan c5c926726d Use enhanced switch expressions where feasible
Closes gh-28014
2022-02-19 14:34:05 +01:00
Phillip Webb 42d114534b Polish BeanDefinitionRegistrar 2022-02-18 17:13:07 +01:00
Sam Brannen 8c5a407a7d Suppress deprecation warnings in tests in build 2022-02-18 16:22:43 +01:00
Sam Brannen 968efb34f6 Merge branch '5.3.x' 2022-02-18 16:18:36 +01:00
Sam Brannen 6c832598c9 Merge branch '5.3.x' 2022-02-18 15:32:58 +01:00
Juergen Hoeller 4a470e0a37 Prevent @Bean method overloading by default (with enforceUniqueMethods flag)
Closes gh-22609
2022-02-17 22:37:34 +01:00
Juergen Hoeller 41ee23345d Support for registering multiple init/destroy methods on AbstractBeanDefinition
Closes gh-28013
2022-02-17 18:14:09 +01:00
Arjen Poutsma 8506778608 Use JDK 17 on main branch in .sdkmanrc
This commit makes sure that JDK 17 is used on the main branch.
2022-02-17 11:55:25 +01:00
Arjen Poutsma 0814c67913 Merge branch '5.3.x' 2022-02-17 11:53:26 +01:00
Stephane Nicoll b96474707b Merge branch '5.3.x' 2022-02-17 10:07:31 +01:00
Juergen Hoeller 3c0a5fd063 Upgrade to POI 5.2 2022-02-16 20:12:59 +01:00
Juergen Hoeller 69db0f7b45 Merge branch '5.3.x'
# Conflicts:
#	build.gradle
2022-02-16 20:07:55 +01:00
Stephane Nicoll 7f5110a549 Merge branch '5.3.x' 2022-02-16 14:36:50 +01:00
Sam Brannen c1987e5b8c Merge branch '5.3.x' 2022-02-16 12:12:37 +01:00
Arjen Poutsma 3463106532 Merge branch '5.3.x' 2022-02-16 11:24:10 +01:00
Phillip Webb b3306f4e3d Suppress deprecation warning in WebAsyncManagerTests
See gh-27959
2022-02-15 15:11:31 -08:00
Phillip Webb 18b8e4ec5c Add mavenCentral() to pluginManagement repositories
Update the pluginManagement repositories used by Grade to include
`mavenCentral()` since `gradlePluginPortal()` has been suffering
from timeouts recently.
2022-02-15 15:11:31 -08:00
Sam Brannen 2cee63491d Remove deprecated SocketUtils
Closes gh-28052
2022-02-15 16:19:11 +01:00
Sam Brannen bbd35ded91 Stop using SocketUtils in ActiveMQ STOMP broker tests
See gh-28052
2022-02-15 15:53:43 +01:00
Stephane Nicoll 5fbd01f28f Polish 2022-02-15 15:25:45 +01:00
Sam Brannen d2d54c826f Increase max memory for Gradle to 2048m 2022-02-15 14:59:26 +01:00
Sam Brannen c42023f20e Stop using SocketUtils in WebClientIntegrationTests
See gh-28052
2022-02-15 14:59:26 +01:00
Sam Brannen 552e02cb44 Polishing 2022-02-15 14:44:46 +01:00
Sam Brannen 7412625929 Merge branch '5.3.x'
# Conflicts:
#	spring-web/src/test/java/org/springframework/remoting/caucho/CauchoRemotingTests.java
#	spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java
2022-02-15 14:35:25 +01:00
Sam Brannen 11de64d609 Merge branch '5.3.x' 2022-02-15 13:48:22 +01:00
Stephane Nicoll c732b56edd Merge branch '5.3.x' 2022-02-15 13:40:47 +01:00
Stephane Nicoll 2141373c43 Introduce AOT variant of BeanPostProcessor
This commit introduces an optional interface that a BeanPostProcessor
can implement to opt-in for providing a generated code equivalent of
what it does with a regular runtime.

This commit has a first implementation of this interface with
AutowiredAnnotationBeanPostProcessor replacing its processing of
autowired annotations by generated code.

Closes gh-27921
2022-02-15 13:27:07 +01:00
Stephane Nicoll 5bbc7dbce2 Polish ProtectedAccess options
This commit improves how protected access analysis operates. Rather than
providing a static boolean, a function callback for the member to
analyse is used. This permits to change the decision whether reflection
can be used, or if the return type is assigned.

Both of those are already applicable, with InjectionGenerator relying
on reflection for private fields, and DefaultBeanInstanceGenerator
assigning the bean instance if additional contributors are present.

This commit also moves the logic of computing the options where the code
is actually generated.

See gh-28030
2022-02-15 13:16:39 +01:00
rstoyanchev 4782d4c080 Merge branch '5.3.x' into main 2022-02-14 20:52:09 +00:00
Stephane Nicoll c5e1a774a5 Add bean instance generator infrastructure
This commit provides the necessary infrastructure to let components
contribute statements that are used to fully instantiate a bean
instance.

To ease code generation, a dedicated infrastructure to register bean
definition is provided in the o.s.beans.factory.generator package.
BeanDefinitionRegistrar offers a builder style API that provides a way
to hide how injected elements are resolved at runtime and let
contributors provide code that may throw a checked exception.

BeanInstanceContributor is the interface that components can implement
to contribute to a bean instance setup. DefaultBeanInstanceGenerator
generates, for a particular bean definition, the necessary statements
to instantiate a bean.

Closes gh-28047
2022-02-14 17:01:32 +01:00
Brian Clozel bfe9d4fc49 Merge branch '5.3.x' 2022-02-14 16:23:49 +01:00
Brian Clozel 4c410cbe54 Remove toolchain configuration for Kotlin
Kotlin currently only supports JDK17 language level, which is our
minimum requirement so far.
This commit simplifies the toolchain setup until this is needed again.

See 303e363adf
2022-02-14 13:04:09 +01:00
rstoyanchev 7ecfce2386 Polishing contribution
See gh-27948
2022-02-14 11:26:40 +00:00
heowc ad2722b3a3 MissingServletRequestPartException extends ServletRequestBindingException
Closes gh-27948
2022-02-14 11:26:40 +00:00
Brian Clozel 303e363adf Configure Gradle JVM toolchain for Kotlin tasks 2022-02-14 11:47:16 +01:00
Brian Clozel 2a0ec0b2dd Merge branch '5.3.x' 2022-02-14 10:56:44 +01:00
Sébastien Deleuze 5e64081ed1 Merge branch '5.3.x' 2022-02-14 10:51:46 +01:00
Brian Clozel 70269addb7 Merge branch '5.3.x' 2022-02-14 10:38:41 +01:00
Sam Brannen e6ce328be4 Merge branch '5.3.x'
# Conflicts:
#	spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java
2022-02-13 00:00:11 +01:00
Sam Brannen 7b0443333d Merge branch '5.3.x'
# Conflicts:
#	build.gradle
2022-02-11 20:44:42 +01:00
Stephane Nicoll 37b03aee82 Merge branch '5.3.x' 2022-02-11 15:49:53 +01:00
Sam Brannen a4e192e33d Merge branch '5.3.x'
# Conflicts:
#	spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java
2022-02-11 15:38:54 +01:00
Sam Brannen 5ae9217271 Merge branch '5.3.x'
# Conflicts:
#	spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java
#	src/eclipse/org.eclipse.jdt.ui.prefs
2022-02-11 15:01:47 +01:00
Brian Clozel 7257f31ca8 Upgrade Dokka to 1.6.10 2022-02-11 13:58:56 +01:00
Brian Clozel 6c42bcfaec Upgrade to Kotlin 1.6.20-M1
This commit upgrades the Kotlin dependencies to 1.6.20-M1 and configures
the build to generate Java 17 bytecode for Kotlin classes.

Closes gh-27814
2022-02-11 11:39:32 +01:00
Brian Clozel 2019e176ee Upgrade to AspectJ 1.9.8
This commit also upgades the dedicated Gradle plugin for AspectJ build
integration.

Closes gh-27416
2022-02-11 11:13:52 +01:00
Stephane Nicoll 1a4573641d Add code contribution infrastructure
This commit adds an API that lets individual components contribute code,
runtime hints, and protected access information. This ease the cases
where code need to be written in a privileged package if necessary and
let contributors provide hints for the code they generate.

Closes gh-28030
2022-02-10 15:54:43 +01:00
Stephane Nicoll d64f8c1a05 Make BeanDefinitionValueResolver public
Closes gh-28029
2022-02-10 15:01:58 +01:00
Stephane Nicoll b3ceb0f625 Add core JavaPoet utilities
This commit adds utilities that facilitate code generation patterns
used by the AOT engine.

Closes gh-28028
2022-02-10 14:58:04 +01:00
Stephane Nicoll dfae8effa8 Repackage Javapoet in org.springframework.javapoet
This commit repackages the Javapoet library into spring-core so that it
can be used by the AOT engine without requiring a specific version.

Closes gh-27828
2022-02-10 14:56:36 +01:00
Stephane Nicoll 7a2c9b80c2 Merge branch '5.3.x' 2022-02-10 13:15:39 +01:00
Sam Brannen 5c60a721a7 Upgrade to Gradle 7.4
Closes gh-28020
2022-02-08 16:26:37 +01:00
Sam Brannen 1deb6b04b8 Apply "instanceof pattern matching" in SynthesizedMergedAnnotationInvocationHandler 2022-02-08 14:30:26 +01:00
Sam Brannen 839cc5f7f8 Remove unnecessary JDK 9+ check in MergedAnnotationsTests 2022-02-08 14:19:32 +01:00
Sam Brannen bf40033e86 Merge branch '5.3.x' 2022-02-08 14:15:25 +01:00
Stephane Nicoll a0c97e4c36 Polish
See gh-27829
2022-02-07 12:51:53 +01:00
Stephane Nicoll 6936f7e0cb Relocate runtime hints to aot package
See gh-27829
2022-02-07 12:51:43 +01:00
Sam Brannen e077a753f8 Polish JsonContentTests 2022-02-05 20:37:42 +01:00
Sam Brannen 2ae6431a50 Merge branch '5.3.x' 2022-02-05 20:26:10 +01:00
Sam Brannen 04fbfddb13 Polish contribution
See gh-28011
2022-02-05 19:12:13 +01:00
lijun695 1e0e477833 Apply "instanceof pattern matching" in AbstractRoutingDataSource
Closes gh-28011
2022-02-05 18:58:08 +01:00
Stephane Nicoll 9a0f691e86 Merge branch '5.3.x' 2022-02-05 13:59:45 +01:00
Juergen Hoeller b0bca7f5ae Merge branch '5.3.x'
# Conflicts:
#	build.gradle
2022-02-04 23:55:18 +01:00
Juergen Hoeller 3eb9886724 Merge branch '5.3.x'
# Conflicts:
#	spring-context-support/src/main/java/org/springframework/scheduling/commonj/WorkManagerTaskExecutor.java
#	spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java
#	spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java
#	spring-tx/src/main/java/org/springframework/jca/work/SimpleTaskWorkManager.java
#	spring-tx/src/main/java/org/springframework/jca/work/WorkManagerTaskExecutor.java
2022-02-04 23:24:21 +01:00
Juergen Hoeller d07e1be623 Retrieve JDBC Connection via JdbcCoordinator (for compatibility with Hibernate 6)
Closes gh-28007
2022-02-04 22:24:50 +01:00
Juergen Hoeller 6b1c2dc944 Consistently override (and prevent overriding for) aliases with bean definitions
Closes gh-27866
2022-02-04 21:12:42 +01:00
Juergen Hoeller e5af4aa608 Initial upgrade to R2DBC Borca
See gh-27976
2022-02-04 21:09:02 +01:00
Juergen Hoeller 9688e61e20 Upgrade to Groovy 4.0
Closes gh-27985
2022-02-04 21:01:02 +01:00
Sam Brannen 4358b48b08 Merge branch '5.3.x' 2022-02-04 20:01:48 +01:00
Stephane Nicoll c064e90697 Merge branch '5.3.x' 2022-02-04 09:24:50 +01:00
Sam Brannen b3f786728e Use modern language features in tests 2022-02-03 15:35:32 +01:00
Sam Brannen 32cd73261a Apply "switch expressions" where applicable 2022-02-03 15:21:18 +01:00
Sam Brannen 9a5ecd0c46 Apply "instanceof pattern matching" in spring-r2dbc 2022-02-03 15:21:09 +01:00
Sam Brannen 12342d7f8e Sync ScriptUtilsUnitTests implementations 2022-02-03 15:20:54 +01:00
Sam Brannen c263cbfbe4 Fix broken test missed in merge 2022-02-03 15:16:27 +01:00
Sam Brannen 54565e95b5 Merge branch '5.3.x' 2022-02-03 14:58:36 +01:00
Brian Clozel 5ad261228d Upgrade JDK 17 and JDK 18 versions in CI image 2022-02-03 10:22:43 +01:00
Stephane Nicoll d94298aae5 Merge branch '5.3.x' 2022-02-03 09:58:21 +01:00
rstoyanchev 823958bcc5 Merge branch '5.3.x' into main
Remove use of Mockito spy proxies, which don't work on Java 17.
2022-02-02 17:35:54 +00:00
Arjen Poutsma 6e4551131d Merge branch '5.3.x' 2022-02-01 13:52:52 +01:00
Stephane Nicoll 84ebbdd38e Merge branch '5.3.x' 2022-01-31 09:34:54 +01:00
Sam Brannen 5378f2040d Merge branch '5.3.x' 2022-01-30 15:51:58 +01:00
Sam Brannen 24ff2d2b6f Merge branch '5.3.x' 2022-01-30 15:45:55 +01:00
Sam Brannen e3529453d1 Remove dependency management for groovy-test
groovy-test is no longer used in the build.

See gh-27945
2022-01-29 17:29:31 +01:00
Sam Brannen de33e3b575 Merge branch '5.3.x' 2022-01-29 12:43:18 +01:00
Sam Brannen ed2696287a Stop applying Groovy plugin for the root Gradle project
The root project does not rely on the Groovy plugin.

See gh-27945
2022-01-28 16:55:05 +01:00
Sam Brannen 8e2bb5f3af Merge branch '5.3.x' 2022-01-28 16:40:58 +01:00
Sam Brannen e5129c58f4 Merge branch '5.3.x' 2022-01-28 16:18:13 +01:00
Arjen Poutsma a9a6b071d9 Merge branch '5.3.x' 2022-01-28 13:45:45 +01:00
Sam Brannen 786d80c0bb Merge branch '5.3.x' 2022-01-27 16:13:55 +01:00
Stephane Nicoll 29768cdd11 Merge branch '5.3.x' 2022-01-27 09:55:55 +01:00
Sam Brannen 4d54e5ad87 Merge branch '5.3.x' 2022-01-26 17:34:28 +01:00
Stephane Nicoll 84e6d2a95c Merge branch '5.3.x' 2022-01-26 14:12:26 +01:00
Sam Brannen f64cc08b62 Apply "instanceof pattern matching" in additional core classes 2022-01-26 13:49:50 +01:00
Sam Brannen e7b9d61225 Merge branch '5.3.x' 2022-01-26 12:32:25 +01:00
Juergen Hoeller c58885fc35 Upgrade to Hibernate ORM 5.6.5, Eclipse Yasson 2.0.4, JRuby 9.3.3 2022-01-26 00:24:01 +01:00
Juergen Hoeller 065ac8e081 Merge branch '5.3.x'
# Conflicts:
#	build.gradle
#	spring-orm/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java
2022-01-26 00:06:12 +01:00
Stephane Nicoll 48ce714d15 Provide an API to record various runtime hints
This commit provides an API to record the need for reflection,
resources, serialization, and proxies so that the runtime can be
optimized accordingly.

`RuntimeHints` provides an entry point to register the following:

* Reflection hints: individual elements of a type can be defined, as
well as a predefined categories (identified by the `MemberCategory`
enum). A method or constructor hint can refine whether the executable
should only be introspected or also invoked.
* Resource hints: patterns using includes/excludes identify the
resources to include at runtime. Resource bundles are also supported.
* Java Serialization hints: types that use java serialization can be
registered.
* Proxy hints: both interfaces-based (JDK) proxy and class-based proxy
can be defined.

This commit also introduces a `TypeReference` abstraction that permits
to record hints for types that are not available on the classpath, or
not compiled yet (generated code).

Closes gh-27829
2022-01-25 15:45:40 +01:00
Sam Brannen 72fc706c22 Merge branch '5.3.x' 2022-01-25 10:03:51 +01:00
Sam Brannen 08daacfc1b Merge branch '5.3.x' 2022-01-24 20:33:51 +01:00
Stephane Nicoll f9a19c749b Merge branch '5.3.x' 2022-01-22 10:42:18 +01:00
Sam Brannen 54c7f53eff Avoid use of var declarations
See gh-27945.
2022-01-21 19:25:44 +01:00
Sam Brannen b943a7a07c Merge branch '5.3.x' 2022-01-21 16:09:40 +01:00
Sam Brannen a323c39e97 Remove Groovy from "Eclipse/STS Project Import Guide"
Groovy support is no longer required in the IDE due to gh-27945.
2022-01-21 11:27:09 +01:00
Sam Brannen 9af2c9d55d Overhaul GroovyBeanDefinitionReaderTests
This commit switches from CGLIB-based proxies to JDK dynamic proxies
for AOP and scoped-bean tests, in order to be able to run tests in the
Eclipse IDE without special Run Configuration setup for the Java module
system.

This commit also simplifies the loading of beans defined with the Groovy
DSL.

See gh-27945
2022-01-21 11:16:35 +01:00
Sam Brannen e94e67cd93 Polish GroovyApplicationContextTests
See gh-27945
2022-01-21 11:16:35 +01:00
Sam Brannen 1cf2960eb6 Use AssertJ instead of Groovy Assertions
See gh-27945
2022-01-21 11:16:35 +01:00
Sam Brannen a6deac3ffe Polish contribution
See gh-27945
2022-01-21 10:33:32 +01:00
Dave Syer f7c3706361 Port GroovyDynamicElementReader to Java
Prior to this commit, GroovyDynamicElementReader was implemented in
Groovy, which required that developers have Groovy language support
installed and configured in their IDEs.

This commit ports GroovyDynamicElementReader from Groovy to Java,
making the compilation much simpler and allowing developers to open the
project in Eclipse or VSCode (or other IDEs without Groovy support)
without compiler errors.

This commit also converts related tests from Groovy to Java.

Closes gh-27945
2022-01-20 17:42:17 +01:00
Sam Brannen 912bb16e44 Merge branch '5.3.x' 2022-01-20 15:54:50 +01:00
Juergen Hoeller 66732afc10 Merge branch '5.3.x'
# Conflicts:
#	build.gradle
#	spring-jms/src/main/java/org/springframework/jms/listener/AbstractPollingMessageListenerContainer.java
2022-01-19 13:56:37 +01:00
Sam Brannen e565d2cabb Apply "instanceof pattern matching" in PropertySourcesPlaceholderConfigurer
See gh-27947
2022-01-18 16:23:41 +01:00
Sam Brannen d72cf89ebf Make PropertySourcesPlaceholderConfigurerTests pass on JDK 17
This change is required in Eclipse IDE but not for the Gradle build.

See gh-27947
2022-01-18 16:21:26 +01:00
Sam Brannen 4a51e4bbc7 Merge branch '5.3.x' 2022-01-18 16:16:10 +01:00
Sam Brannen 4388a7c4d0 Merge branch '5.3.x' 2022-01-17 18:05:06 +01:00
Sam Brannen 19da4e309f Merge branch '5.3.x' 2022-01-17 16:55:08 +01:00
Sam Brannen 316e84f04f Polish contribution
See gh-27908
2022-01-14 15:53:41 +01:00
Frank Chen f43fb41bce Simplify debugging of Undertow transferTo issue
This commit introduces a dedicated (disabled) transferToWithUndertow()
test method to simplify debugging of transferTo issues with Undertow.

See gh-25310
Closes gh-27908
2022-01-14 15:44:29 +01:00
Sam Brannen a849f76586 Merge branch '5.3.x' 2022-01-13 17:57:14 +01:00
Sam Brannen 198576dbc5 Merge branch '5.3.x' 2022-01-13 16:21:16 +01:00
Stephane Nicoll 680ec30148 Merge branch '5.3.x' 2022-01-13 13:23:25 +01:00
Brian Clozel 2d9c9fe9cc Configure Spring Milestone repository for apiDiff task
Prior to this commit, the `apiDiff` custom Gradle task would only use
the configured repositories in the build to generated the API diff
report. This causes issues when the report has to be generated against a
previous milestone: the Spring Framework build only relies on Maven
Central and a specific `libs-spring-framework-build` repository for
building the project. In this case, the task cannot resolve the previous
milestone artifacts to generate the report.

This commit improves the `ApiDiffPlugin` to automatically add the Spring
Milestone repository to the root project configuration when the task is
executed.

Fixes gh-27928
2022-01-13 12:24:39 +01:00
Stephane Nicoll d6e56ce327 Merge branch '5.3.x' 2022-01-13 08:39:12 +01:00
Sam Brannen 148d7ab1df Merge branch '5.3.x' 2022-01-12 17:13:03 +01:00
Juergen Hoeller 4b68dfb6f5 Upgrade to Hibernate ORM 5.6.3, Hibernate Validator 7.0.2, Jackson 2.13.1 2022-01-12 16:42:15 +01:00
Juergen Hoeller 50faa29329 Merge branch '5.3.x'
# Conflicts:
#	build.gradle
2022-01-12 16:38:19 +01:00
rstoyanchev 12315d5b20 Merge branch '5.3.x' into main 2022-01-12 15:06:10 +00:00
rstoyanchev d61d0d41a3 Merge branch '5.3.x' into main 2022-01-12 09:02:07 +00:00
Stephane Nicoll b56815f995 Merge branch '5.3.x' 2022-01-12 09:40:15 +01:00
rstoyanchev 6643efe0b4 Merge branch '5.3.x' into main 2022-01-11 18:48:49 +00:00
rstoyanchev 3477ec0a35 Decode servletPath in HtmlUnitRequestBuilder
Closes gh-27837
2022-01-11 14:54:14 +00:00
rstoyanchev 9346c89f5c Polishing in HtmlUnitRequestBuilder
Order methods according to Spring Framework conventions.
Order request initialization by URI component.

See gh-27837
2022-01-11 14:33:12 +00:00
rstoyanchev 29fe109440 SockJS TaskScheduler container bean is package private
See gh-27903
2022-01-11 13:59:03 +00:00
Sam Brannen 5aefcd2fdb Re-enable BlockHound integration tests
Prior to this commit, our BlockHound integration tests were disabled
after the migration to a JDK 17 baseline since the build now always
runs on JDK 14 or higher.

To re-enable the tests we now supply the deprecated
-XX:+AllowRedefinitionToAddDeleteMethods command-line argument to the JVM
for tests in the Gradle build. Users can also configure this manually
within an IDE to run SpringCoreBlockHoundIntegrationTests.

If that command-line argument is removed from the JVM at some point in
the future, we will need to investigate an alternative solution.

See https://github.com/reactor/BlockHound/issues/33 for details.
2022-01-11 14:54:59 +01:00
Sam Brannen f2fe8a87fa Polish contribution
See gh-27862
2022-01-11 14:11:07 +01:00
v_vyqyxiong 6ecb488327 Remove unnecessary check in isBridgedCandidateFor()
In BridgeMethodResolver#isBridgedCandidateFor, candidateMethod is never
not bridged, so it's unnecessary to judge whether candidateMethod and
bridgeMethod are the same.

Closes gh-27862
2022-01-11 14:03:57 +01:00
Arjen Poutsma b848acd86d Merge branch '5.3.x' 2022-01-11 13:44:45 +01:00
rstoyanchev 368201975a Hide default SockJS TaskScheduler for @EnableWebSocket
Closes gh-27903
2022-01-11 10:16:27 +00:00
Sam Brannen d57bc176f2 Merge branch '5.3.x' 2022-01-10 14:21:25 +01:00
Sam Brannen 4ebc53a424 Merge branch '5.3.x' 2022-01-10 13:28:31 +01:00
Arjen Poutsma 1941ae6696 Merge branch '5.3.x' 2022-01-10 11:01:38 +01:00
Stephane Nicoll 3c500aa000 Merge branch '5.3.x' 2022-01-10 10:13:17 +01:00
Sam Brannen 5a76939a15 Merge branch '5.3.x' 2022-01-09 17:26:48 +01:00
Sam Brannen 519fa60c25 Merge branch '5.3.x' 2022-01-09 17:12:49 +01:00
Sam Brannen 5d508de2c0 Merge branch '5.3.x' 2022-01-09 16:17:42 +01:00
Sam Brannen ab88ff374a Merge branch '5.3.x' 2022-01-08 17:24:53 +01:00
Sam Brannen 86387db045 Merge branch '5.3.x' 2022-01-08 17:07:34 +01:00
Sam Brannen ae5d8b645b Merge branch '5.3.x' 2022-01-08 16:36:21 +01:00
Sam Brannen b981e36174 Merge branch '5.3.x' 2022-01-07 16:18:52 +01:00
Sam Brannen e1991f981a Merge branch '5.3.x' 2022-01-07 15:55:18 +01:00
Sam Brannen 7769ded887 Merge branch '5.3.x' 2022-01-07 14:31:32 +01:00
springmonster aaa10e9060 Simplify HashMap declaration in test fixture
Co-authored-by: kuanghc1 <kuanghc1@lenovo.com>

Closes gh-27900
2022-01-07 10:15:39 +01:00
Stephane Nicoll 7c637f01c4 Merge branch '5.3.x' 2022-01-06 16:49:17 +01:00
Sam Brannen 338f8907ac Merge branch '5.3.x' 2022-01-04 16:51:06 +01:00
Sam Brannen 83827031a7 Merge branch '5.3.x' 2022-01-04 16:28:02 +01:00
Sam Brannen 202b7ea47b Merge branch '5.3.x' 2022-01-04 15:17:05 +01:00
Sam Brannen eb783e6690 Merge branch '5.3.x' 2022-01-04 14:52:50 +01:00
Sam Brannen 61c3d7a989 Merge branch '5.3.x' 2022-01-04 14:09:02 +01:00
liuzhifei ee292ec116 Replace use of StringBuffer with StringBuilder
With JDK 9, java.util.regex.Matcher received overloaded variants of
appendReplacement() and appendTail() that accept a StringBuilder,
allowing us to replace the use of StringBuffer with StringBuilder.

Closes gh-27884
2022-01-04 13:14:17 +01:00
Marten Deinum 948f5999c3 Replace use of StringBuffer with StringBuilder
With JDK 9, java.util.regex.Matcher received overloaded variants of
appendReplacement() and appendTail() that accept a StringBuilder,
allowing us to replace the use of StringBuffer with StringBuilder.

Closes gh-27822
2022-01-04 13:14:17 +01:00
Sam Brannen 2ed7268ded Remove deprecated AbstractBeanDefinitionReader.getBeanFactory() method
The getBeanFactory() method (which is deprecated since Spring Framework
5.3.15) has been obsolete for more than 13 years since it was superseded
by the getRegistry() method in the BeanDefinitionReader interface.

Closes gh-27875
2022-01-04 12:55:13 +01:00
Sam Brannen 7311620915 Merge branch '5.3.x' 2022-01-04 12:51:23 +01:00
Marten Deinum 941b6af9ac Use Collection factory methods when applicable
This commit replaces the use of Collections.unmodifiableList/Set/Map
with the corresponding 'of(...)' factory methods introduced in Java 9.

Closes gh-27824
2022-01-04 12:01:13 +01:00
a.yazychyan ab240f5d8e Use String.repeat() and pattern matching instanceof
Closes gh-27834
2022-01-03 17:11:23 +01:00
liuzhifei 7021eb5bb1 Apply "instanceof pattern matching" in additional locations
Closes gh-27696
2022-01-03 16:52:38 +01:00
Sam Brannen 6555d3b42d Suppress warnings in tests 2022-01-03 16:12:14 +01:00
Sam Brannen 97625e3658 Additional changes because HttpMethod changed from enum to class
See gh-27697
2022-01-03 16:12:14 +01:00
Sam Brannen 1dee80e750 Upgrade to Gradle 7.3.3 2022-01-03 15:59:37 +01:00
Sébastien Deleuze 0b8c815c6f Upgrade Kotlin serialization to 1.3.2
Closes gh-27879
2022-01-03 15:48:27 +01:00
Sébastien Deleuze a410f4c0f2 Upgrade Kotlin Coroutines to 1.6.0
Closes gh-27878
2022-01-03 15:45:37 +01:00
Sam Brannen b24cbc5e97 Merge branch '5.3.x' 2022-01-03 12:01:15 +01:00
Stephane Nicoll eb5022924e Merge pull request #27852 from xixingya
* pr/27852:
  Polish "Fix typo and use of componentry"
  Fix typo and use of componentry

Closes gh-27852
2021-12-29 11:06:23 +01:00
Stephane Nicoll 900e0f56eb Polish "Fix typo and use of componentry"
See gh-27852
2021-12-29 11:05:27 +01:00
liuzhifei 65d2e9bb54 Fix typo and use of componentry
See gh-27852
2021-12-29 11:01:41 +01:00
Stephane Nicoll 7f73cb6726 Merge pull request #27864 from izeye
* pr/27864:
  Update copyright year of changed file
  Remove AsyncConfigurerSupport reference in EnableAsync Javadoc

Closes gh-27864
2021-12-29 10:56:40 +01:00
Stephane Nicoll 8a7a046bf0 Update copyright year of changed file
See gh-27864
2021-12-29 10:56:29 +01:00
izeye 88d4eac537 Remove AsyncConfigurerSupport reference in EnableAsync Javadoc
See gh-27864
2021-12-29 10:56:02 +01:00
Stephane Nicoll c09a674dcb Merge pull request #27863 from izeye
* pr/27863:
  Update copyright year of changed file
  Remove references to JCacheConfigurerSupport and CachingConfigurerSupport

Closes gh-27863
2021-12-29 10:55:54 +01:00
Stephane Nicoll c204cc7ba0 Update copyright year of changed file
See gh-27863
2021-12-29 10:54:49 +01:00
izeye f0125afb5e Remove references to JCacheConfigurerSupport and CachingConfigurerSupport
See gh-27863
2021-12-29 10:53:56 +01:00
Stephane Nicoll 7ba089be95 Temporarily remove references to JBoss AS Javadoc
See gh-27860
2021-12-27 17:34:48 +01:00
Stephane Nicoll 414169b1eb Merge pull request #27848 from izeye
* pr/27848:
  Polish "Add Javadoc since to new PayloadApplicationEvent constructor"
  Add Javadoc since to new PayloadApplicationEvent constructor

Closes gh-27848
2021-12-27 12:17:27 +01:00
Stephane Nicoll 772630caf1 Polish "Add Javadoc since to new PayloadApplicationEvent constructor"
See gh-27848
2021-12-27 12:15:27 +01:00
izeye f3fd7b156e Add Javadoc since to new PayloadApplicationEvent constructor
See gh-27848
2021-12-27 12:14:44 +01:00
Stephane Nicoll 544e9bb403 Merge pull request #24525 from chenqimiao
* pr/24525:
  Polish "Reuse ResolvableType in getDependencyType"
  Reuse ResolvableType in getDependencyType

Closes gh-24525
2021-12-21 11:20:12 +01:00
Stephane Nicoll f1fe16e3cd Polish "Reuse ResolvableType in getDependencyType"
See gh-24525
2021-12-21 11:17:53 +01:00
陈其苗 b69ab8d568 Reuse ResolvableType in getDependencyType
See gh-24525
2021-12-21 11:17:31 +01:00
Stephane Nicoll f64ede3c83 Merge pull request #24636 from chenqimiao
* pr/24636:
  Update copyright year of changed file
  Use Collections.addAll instead of Collection.addAll

Closes gh-24636
2021-12-21 09:50:09 +01:00
Stephane Nicoll ca6911a532 Update copyright year of changed file
See gh-24636
2021-12-21 09:49:08 +01:00
陈其苗 dbbdd044cd Use Collections.addAll instead of Collection.addAll
See gh-24636
2021-12-21 09:47:30 +01:00
Stephane Nicoll 5532615361 Merge pull request #27827 from izeye
* pr/27827:
  Polish

Closes gh-27827
2021-12-21 09:37:09 +01:00
izeye 713795cc34 Polish
See gh-27827
2021-12-21 09:36:08 +01:00
Stephane Nicoll fa78fb4351 Merge pull request #27833 from izeye
* pr/27833:
  Polish formatting
  Polish HtmlCharacterEntityDecoder

Closes gh-27833
2021-12-21 09:35:02 +01:00
Stephane Nicoll ac1032ffc9 Polish formatting
See gh-27833
2021-12-21 09:34:39 +01:00
izeye 731af9444c Polish HtmlCharacterEntityDecoder
See gh-27833
2021-12-21 09:32:46 +01:00
Stephane Nicoll db21cbd4af Merge pull request #27835 from izeye
* pr/27835:
  Polish formatting
  Polish HttpMethod

Closes gh-27835
2021-12-21 09:27:25 +01:00
Stephane Nicoll 1aaf5262b1 Polish formatting
See gh-27835
2021-12-21 09:22:03 +01:00
izeye 08a34ca1ec Polish HttpMethod
See gh-27835
2021-12-21 09:20:29 +01:00
Stephane Nicoll ec9ce5b4b0 Merge branch '5.3.x' 2021-12-16 15:30:32 +01:00
Juergen Hoeller 9dc5c9f935 Merge branch '5.3.x'
# Conflicts:
#	build.gradle
2021-12-15 21:52:16 +01:00
Juergen Hoeller e15bed781d Upgrade to POI 5.1 2021-12-15 18:15:39 +01:00
Juergen Hoeller 96e2fc69ed Merge branch '5.3.x'
# Conflicts:
#	build.gradle
#	spring-core/src/main/java/org/springframework/core/type/StandardAnnotationMetadata.java
#	spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadata.java
2021-12-15 18:03:51 +01:00
Juergen Hoeller 50c7c84886 Introduce getDeclaredMethods() for MethodMetadata of all user-declared methods
Closes gh-27701
2021-12-15 13:32:42 +01:00
dramatist efaccd6356 Apply "instanceof pattern matching" in spring-beans 2021-12-15 13:14:42 +01:00
Stephane Nicoll 2f3a9dbc68 Deprecate CachingConfigurerSupport and AsyncConfigurerSupport
Closes gh-27813
2021-12-15 12:03:39 +01:00
Stephane Nicoll b6faaf1fc1 Merge branch '5.3.x' 2021-12-15 10:59:50 +01:00
Stephane Nicoll 73ee87aadf Merge branch '5.3.x' 2021-12-15 09:50:13 +01:00
Rossen Stoyanchev b7cd049d7d Add "application/*+json" to MappingJackson2MessageConverter
Closes gh-20269
2021-12-14 21:59:22 +00:00
Juergen Hoeller bdbcc4f98c Merge branch '5.3.x'
# Conflicts:
#	build.gradle
2021-12-14 18:37:46 +01:00
Juergen Hoeller 3e6eb987d0 Clean up 5.3.x merge result
See gh-27726
2021-12-14 17:01:17 +01:00
Juergen Hoeller bfdb93b406 Merge branch '5.3.x'
# Conflicts:
#	build.gradle
#	src/docs/asciidoc/integration.adoc
2021-12-14 16:51:00 +01:00
Sébastien Deleuze ea9b8c1d0f Upgrade Dokka to 1.6.0
Closes gh-27815
2021-12-14 16:49:13 +01:00
Stephane Nicoll c5c2053b63 Merge branch '5.3.x' 2021-12-14 15:35:48 +01:00
Brian Clozel bb53a99def Upgrade to Kotlin 1.6.10
Closes gh-27413
2021-12-14 15:25:50 +01:00
Stephane Nicoll 8d93dc4abb Merge branch '5.3.x' 2021-12-14 14:05:18 +01:00
Kwangyong Kim ceea00f733 Fix cache annotation tip
Even if using cglib proxy mode, annotations on an interface can be recognized.

Signed-off-by: Kwangyong Kim <banana.yong@gmail.com>
2021-12-14 13:51:20 +01:00
Juergen Hoeller 2fb3f9993f Upgrade to AspectJ 1.9.8 RC3
Closes gh-27537
2021-12-14 13:43:44 +01:00
Juergen Hoeller 64b6beed5b Consistent support for square brackets around named parameter
See gh-27716
2021-12-14 11:34:48 +01:00
Anton Naydenov 86eda279c8 Support SQUARE brackets [] around NAMED parameter 2021-12-14 11:24:38 +01:00
Juergen Hoeller aeff664cf9 Polishing 2021-12-14 09:46:52 +01:00
Juergen Hoeller ba468a731f Remove JamonPerformanceMonitorInterceptor support
Includes upgrade to Tomcat 10.0.14, Undertow 2.2.14, Apache HttpClient 5.1.2, Hibernate ORM 5.6.2, Mockito 4.1.

Closes gh-27786
2021-12-14 09:46:08 +01:00
Juergen Hoeller 9a513cfdea Enforce Future/void return declaration for async methods
Closes gh-27734
2021-12-14 09:44:12 +01:00
Juergen Hoeller 37bebeaaaf Accept protected @Transactional/Cacheable methods on CGLIB proxies
Closes gh-25582
2021-12-14 09:41:23 +01:00
Rossen Stoyanchev 32b8710489 Typo
See gh-22154
2021-12-14 07:31:18 +00:00
Rossen Stoyanchev 3600644ed1 Require type-level @Controller annotation
Closes gh-22154
2021-12-14 07:09:08 +00:00
Rossen Stoyanchev 2db6795a1a Polishing contribution
Closes gh-27722
2021-12-13 21:03:58 +00:00
조현수(Hyunsoo Cho)/Platform Engineering팀/11ST 5d91560f92 Avoid unescape for CONNECT and CONNECTED frames
See gh-27722
2021-12-13 21:03:58 +00:00
Stephane Nicoll 7854dbb025 Merge branch '5.3.x' 2021-12-13 16:19:13 +01:00
Stephane Nicoll 21c3623cdc Merge pull request #27801 from Drezir
* pr/27801:
  Polish formatting
  Polish ExceptionHandlerMethodResolver mapping

Closes gh-27801
2021-12-13 16:01:45 +01:00
Stephane Nicoll 61601de250 Polish formatting
See gh-27801
2021-12-13 15:57:58 +01:00
Adam Ostrožlík 4453102e85 Polish ExceptionHandlerMethodResolver mapping
See gh-27801
2021-12-13 15:57:45 +01:00
Stephane Nicoll 782a94fd25 Merge pull request #27799 from izeye
* pr/27799:
  Polish

Closes gh-27799
2021-12-13 15:03:04 +01:00
izeye 49c4d310b5 Polish
See gh-27799
2021-12-13 14:53:54 +01:00
Stephane Nicoll e822be5a75 Merge pull request #27807 from quaff
* pr/27807:
  Remove unnecessary @SuppressWarnings

Closes gh-27807
2021-12-13 09:37:14 +01:00
Yanming Zhou d836fb4a7a Remove unnecessary @SuppressWarnings
See gh-27807
2021-12-13 09:34:22 +01:00
Stephane Nicoll aa302515a4 Merge branch '5.3.x' 2021-12-12 16:33:54 +01:00
Stephane Nicoll e1acbca4e4 Merge branch '5.3.x' 2021-12-10 15:11:24 +01:00
Sam Brannen 101d92c166 Merge branch '5.3.x' 2021-12-10 13:54:50 +01:00
Sam Brannen 62f480adc3 Merge branch '5.3.x' 2021-12-10 13:13:36 +01:00
Stephane Nicoll 8d6cc7dc10 Merge branch '5.3.x' 2021-12-10 08:03:52 +01:00
Rossen Stoyanchev a15393836c Merge branch '5.3.x' into main 2021-12-09 15:35:21 +00:00
Stephane Nicoll b5ffcfb4ba Merge branch '5.3.x' 2021-12-09 15:19:25 +01:00
Stephane Nicoll 866708942c Merge branch '5.3.x' 2021-12-09 14:44:20 +01:00
Rossen Stoyanchev 3a43ca3a34 Merge branch '5.3.x' into main 2021-12-08 11:41:02 +00:00
Arjen Poutsma ce253041c5 Merge branch '5.3.x' 2021-12-07 13:57:40 +01:00
Arjen Poutsma 81af7330f6 Deprecate StringUtils::trimWhitespace and variants
This commits deprecates
- StringUtils::trimWhitespace in favor of String::strip
- StringUtils::trimLeadingWhitespace in favor of String::stripLeading
- StringUtils::trimTrailingWhitespace in favor of String::stripTrailing

Closes gh-27769
2021-12-06 13:37:16 +01:00
Arjen Poutsma 982ba0e86d Merge pull request #27703 from xixingya:feat/stringstrip
* gh-27703:
  Use String::strip in StringUtils::trimWhitespace
2021-12-06 13:36:46 +01:00
liuzhifei 68cf95f499 Use String::strip in StringUtils::trimWhitespace
See gh-27703
2021-12-06 11:29:43 +01:00
Juergen Hoeller 7f43128a0e Merge branch '5.3.x'
# Conflicts:
#	build.gradle
#	spring-web/src/main/java/org/springframework/web/server/MediaTypeNotSupportedStatusException.java
#	spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java
#	spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java
2021-12-03 22:42:05 +01:00
Stephane Nicoll 110e0f7f2b Add support for Instant in @DateTimeFormat
Closes gh-19846
2021-12-03 16:17:52 +01:00
Arjen Poutsma 0a41da9ec9 Merge branch '5.3.x' 2021-12-03 12:52:30 +01:00
Stephane Nicoll 8144f8666e Merge pull request #1215 from kazuki43zoo
* pr/1215:
  Polish "Add support for YearMonth and MonthDay in @DateTimeFormat"
  Add support for YearMonth and MonthDay in @DateTimeFormat

Closes gh-1215
2021-12-03 11:21:29 +01:00
Stephane Nicoll a57ea39707 Polish "Add support for YearMonth and MonthDay in @DateTimeFormat"
See gh-1215
2021-12-03 11:20:04 +01:00
Kazuki Shimizu 65eceafeee Add support for YearMonth and MonthDay in @DateTimeFormat
See gh-1215
2021-12-03 10:59:38 +01:00
Rossen Stoyanchev a9d2016007 Merge branch '5.3.x' into main 2021-12-03 09:27:11 +00:00
Arjen Poutsma ba568ff79c Merge branch '5.3.x' 2021-12-02 16:12:35 +01:00
Arjen Poutsma 720c30ce84 Merge branch '5.3.x' 2021-12-02 15:12:01 +01:00
Stephane Nicoll 1b4fa0370c Merge pull request #23927 from sokomishalov
* pr/23927:
  Polish "Add Kotlin extensions for Cache and CacheManager"
  Add Kotlin extensions for Cache and CacheManager

Closes gh-23927
2021-12-02 14:51:41 +01:00
Stephane Nicoll 65dc2afe9d Polish "Add Kotlin extensions for Cache and CacheManager"
See gh-23927
2021-12-02 14:51:29 +01:00
sokomishalov 5ec1e20242 Add Kotlin extensions for Cache and CacheManager
See gh-23927
2021-12-02 14:51:29 +01:00
Brian Clozel 24cb1def7d Polish
Closes gh-27754
2021-12-02 14:23:16 +01:00
Rossen Stoyanchev 2d2db530b1 Merge branch '5.3.x' into main 2021-12-02 12:35:48 +00:00
Arjen Poutsma 9cc690a9bb Merge pull request #27356 from ydh6226:patch-1
* gh-27356:
  Use HttpHeaders.ALLOW instead of String constant
2021-12-02 12:32:55 +01:00
ydh6226 a0ba808217 Use HttpHeaders.ALLOW instead of String constant
This commit changes "Allow" strings into HttpHeaders.ALLOW.

See gh-27356
2021-12-02 12:28:36 +01:00
Stephane Nicoll e0979d0e74 Merge pull request #27239 from Frederick888
* pr/27239:
  Update copyright year of changed files
  Replace XMLReaderFactory with SAXParserFactory

Closes gh-27239
2021-12-02 11:33:50 +01:00
Stephane Nicoll e986ff8d07 Update copyright year of changed files
See gh-27239
2021-12-02 11:32:46 +01:00
Frederick Zhang baed0785fd Replace XMLReaderFactory with SAXParserFactory
XMLReaderFactory has been marked as deprecated and without additional
configuration, and it's slower than SAXParserFactory.

Previously `XMLReaderFactory.createXMLReader()` is called upon every
request. This is an anti-pattern as mentioned in [1] and it can be very
slow since it loads the jar service file unless a parser has been
pre-assigned [2] (e.g. by setting org.xml.sax.driver).

SAXParserFactory uses a FactoryFinder [3] instead, which takes advantage
of a thread-local cache provided by ServiceLoader. Developers can still
pre-assign a factory by setting javax.xml.parsers.SAXParserFactory to
make it faster.

[1] https://bugs.openjdk.java.net/browse/JDK-6925410
[2] https://github.com/openjdk/jdk/blob/c8add223a10030e40ccef42e081fd0d8f00e0593/src/java.xml/share/classes/org/xml/sax/helpers/XMLReaderFactory.java#L144-L148
[3] https://github.com/openjdk/jdk/blob/66c653c561b3b5e904579af62e23ff94952bca05/src/java.xml/share/classes/javax/xml/parsers/SAXParserFactory.java#L181-L185

See gh-27239
2021-12-02 11:32:46 +01:00
liuzhifei 32359c52b4 Remove transitive dependency on Java EE 8 JAX-B
Closes gh-27754
2021-12-02 09:37:48 +00:00
Stephane Nicoll 5589e6ceed Merge pull request #24599 from chenqimiao
* pr/24599:
  Polish "Add support for explicit generic type in PayloadApplicationEvent"
  Add support for explicit generic type in PayloadApplicationEvent

Closes gh-24599
2021-12-02 10:23:11 +01:00
Stephane Nicoll 792b366bda Polish "Add support for explicit generic type in PayloadApplicationEvent"
See gh-24599
2021-12-02 10:20:08 +01:00
陈其苗 6283456ef2 Add support for explicit generic type in PayloadApplicationEvent
See gh-24599
2021-12-02 09:38:48 +01:00
Arjen Poutsma 7794606305 Add ClientResponse::createError
This commit introduces ClientResponse::createError, returning
a Mono that terminates with a WebClientException.

Closes gh-27637
2021-12-01 11:10:10 +01:00
Arjen Poutsma 445f25c466 Use HttpMethod::valueOf in HttpMethod::resolve
This commit makes sure that HttpMethod::resolve uses HttpMethod::valueOf
and returns an HttpMethod for non-standard methods.

See gh-27697
2021-11-30 14:59:42 +01:00
Stephane Nicoll 9c1a0d32be Merge pull request #23813 from izeye
* pr/23813:
  Polish contribution
  Polish AbstractResource

Closes gh-23813
2021-11-30 14:33:53 +01:00
Stephane Nicoll 46cb5ab135 Polish contribution
See gh-23813
2021-11-30 14:29:05 +01:00
Johnny Lim 5c4cde7853 Polish AbstractResource
See gh-23813
2021-11-30 14:25:40 +01:00
Arjen Poutsma da3b4cb65d Polish 2021-11-30 14:09:33 +01:00
Arjen Poutsma 7a4207cd7b Changes because HttpMethod changed to class
This commit contains changes made because HttpMethod changed from enum
to class.

See gh-27697
2021-11-30 13:44:36 +01:00
Arjen Poutsma 6e335e3a9f Refactor HTTP Method from Enum to Class
This commit refactors HttpMethod from a Java enum into a class. The
underlying reason being that HTTP methods are not enumerable, but
instead an open range and not limited to the predefined values in the
specifications.

Closes gh-27697
2021-11-30 13:44:36 +01:00
Arjen Poutsma f57004db2c Merge branch '5.3.x' 2021-11-30 13:41:19 +01:00
Sam Brannen a0d54105e9 Use new features in JUnit Jupiter 5.8.2
See gh-27744
2021-11-30 13:00:28 +01:00
Sam Brannen 44950bb862 Merge branch '5.3.x' 2021-11-30 12:27:41 +01:00
Rossen Stoyanchev 1ebe62f646 Merge branch '5.3.x' into main 2021-11-29 17:38:23 +00:00
Stephane Nicoll f88344db03 Merge branch '5.3.x' 2021-11-28 10:54:18 +01:00
Lars Grefer 2f32806bcb Update aspectj-plugin to 6.3.0
Version 6.3.0 aligns with the used Gradle 7.3

Closes gh-27678
2021-11-25 22:19:43 +01:00
Brian Clozel e66095b1a2 Polish
Closes gh-27466
2021-11-25 22:03:11 +01:00
Daniel Le 6605953eb5 Optimize header removal in ForwardedHeaderFilter
The current implementation suggests that the request's headers are not
expected to change. Hence, it's not necessary to copy them.
Furthermore, it might be costly to do so if there are many headers.
Instead, cache only the request's header names for method getHeaderNames.

Methods getHeader and getHeaders delegate to the respective methods of
request if the header name is not in FORWARDED_HEADER_NAMES. Otherwise,
they return null or an empty Enumeration respectively.

See gh-27466
2021-11-25 21:40:21 +01:00
Brian Clozel fab9abd7fe Polish
Closes gh-1581
2021-11-25 19:21:08 +01:00
Tin Pavlinic d178eafc11 Fix SpEL comparison operator for comparable types
Prior to this commit, the SpEL relational operators for comparison
would have the following problem:

* their implementation would claim that incompatible types
  could be compared and later fail during comparison
* not delegate the comparison to the actual `TypeComparator`
  implementation but rely on operator specifics

This commit ensures that the `TypeComparator` implementation is used for
both `canCompare` and `compare` calls in the operators.

See gh-1581
2021-11-25 19:09:52 +01:00
김보배(Bobae Kim)/Platform Engineering팀/11ST 804b343cab Use parseInt without substring method 2021-11-25 16:14:59 +01:00
Brian Clozel 79d3f5c64c Merge branch '5.3.x' 2021-11-24 21:34:55 +01:00
Stephane Nicoll 51ecbdecd8 Merge branch '5.3.x' 2021-11-24 16:29:52 +01:00
Rossen Stoyanchev dcc342ccc5 Merge branch '5.3.x' into main 2021-11-24 13:14:55 +00:00
Stephane Nicoll d5f36c7e2c Merge branch '5.3.x' 2021-11-24 14:02:57 +01:00
Rossen Stoyanchev 975ca284fb Merge branch '5.3.x' into main 2021-11-24 10:45:47 +00:00
Arjen Poutsma 259bcd60fb Change deprecated MimeType specificity usages
This commit changes all code that uses now deprecated methods in
MimeType and MediaType.

See gh-27580
2021-11-23 11:49:01 +01:00
Arjen Poutsma 6d9136013e Refactor MimeType/MediaType specificity
This commit makes several changes to MimeType and MediaType
related to the topic of specificity.

This commit deprecates the MimeType and MediaType Comparators.
Comparators require a transitive relationship, and the desired order for
these types is not transitive (see #27488).

Instead, this commit introduces two new MimeType methods: isMoreSpecific
and isLessSpecific, both of which return booleans. MediaType overrides
these methods to include the quality factor (q) in the comparison.

All MediaType sorting methods have been deprecated in favor of
MimeTypeUtils::sortBySpecificity.  This sorting method now uses
MimeType::isLessSpecific in combination a bubble sort algorithm (which
does not require a transitive compare function).

Closes gh-27580
2021-11-23 11:49:01 +01:00
Arjen Poutsma a7789db067 Polishing 2021-11-23 11:42:34 +01:00
Arjen Poutsma 38062c3373 Polishing contribution
See gh-1607
2021-11-23 11:42:34 +01:00
qxo 247d2bb0ae Repect StaxDriver in XStreamMarshaller::marshalXmlStreamWriter
This commit makes sure that namespaces configured via the streamDriver
property are respected.
2021-11-23 11:42:33 +01:00
Stephane Nicoll 974d326bf5 Merge branch '5.3.x' 2021-11-22 16:17:17 +01:00
Stephane Nicoll 5eafcac3d6 Merge branch '5.3.x' 2021-11-22 13:46:45 +01:00
Stephane Nicoll ac46338fdb Merge branch '5.3.x' 2021-11-22 13:28:09 +01:00
Stephane Nicoll bee0af2b26 Merge branch '5.3.x' 2021-11-22 13:21:28 +01:00
Rossen Stoyanchev 1694691b79 Default to JDK HttpClient if no others present
Closes gh-23432
2021-11-22 12:20:30 +00:00
Rossen Stoyanchev fe8d42ff59 Add JdkHttpClientResourceFactory
See gh-23432
2021-11-22 12:20:30 +00:00
Rossen Stoyanchev b3b50f8f4b Refactoring in the JDK HttpClient support
See gh-23432
2021-11-22 12:20:30 +00:00
Rossen Stoyanchev dcc7154641 Polishing contribution
See gh-23432
2021-11-22 12:20:30 +00:00
Julien Eyraud d930617442 JDK HttpClient connector for WebClient
See gh-21014
2021-11-22 12:20:30 +00:00
Stephane Nicoll ab2b3d91fc Merge branch '5.3.x' 2021-11-22 12:55:56 +01:00
Stephane Nicoll aa80c4873a Merge branch '5.3.x' 2021-11-22 10:31:27 +01:00
Brian Clozel 0b0fab8952 Merge branch '5.3.x' 2021-11-19 15:07:19 +01:00
Arjen Poutsma 9d65ff73f9 Merge branch '5.3.x' 2021-11-19 12:38:06 +01:00
Sam Brannen 2be80b8fc8 Merge branch '5.3.x' 2021-11-18 19:23:49 +01:00
Juergen Hoeller 4750a9430c Early removal of 5.x-deprecated code
Closes gh-27686
2021-11-18 09:18:06 +01:00
Arjen Poutsma 17cdd97c37 Merge branch '5.3.x' 2021-11-17 16:57:02 +01:00
Brian Clozel 62a4a4c0bf Upgrade JDK versions in CI images 2021-11-17 14:07:44 +01:00
Juergen Hoeller b88ed7f4bb Update API version and package references for Jakarta EE 9
Closes gh-27689
See gh-25354
2021-11-17 12:39:23 +01:00
Juergen Hoeller 555807ea9c Update ServletContainerInitializer filename for Jakarta EE 9
Closes gh-27690
See gh-25354
2021-11-17 12:38:58 +01:00
xixingya 5593e1e406 Fix javax.servlet doc to jakarta.servlet (#27692) 2021-11-17 11:29:54 +01:00
Brian Clozel f3b83e7ad4 Merge branch '5.3.x' 2021-11-16 15:05:24 +01:00
Stephane Nicoll c705e32a88 Merge branch '5.3.x' 2021-11-11 09:54:51 +01:00
Brian Clozel ac694eeac8 Upgrade to Gradle 7.3 2021-11-10 19:40:39 +01:00
Arjen Poutsma 33ed92e552 Merge branch '5.3.x' 2021-11-10 16:26:31 +01:00
Christoph Dreis 5c972fcc54 Use Charset variants of URLEncoder and URLDecoder methods 2021-11-10 16:12:11 +01:00
Juergen Hoeller 2fba0bc272 Allow BeanUtils#instantiateClass inlining with native
Closes gh-27072
2021-11-10 15:20:56 +01:00
Juergen Hoeller 54bd66755c Consistently replace String encoding names with StandardCharset arguments
Closes gh-27664
2021-11-10 15:19:51 +01:00
SungMin 32af39d6e6 Use 'toString(Charset)' instead of 'toString(String)' for encodings (#27646)
Co-authored-by: 홍성민(SungMin Hong)/Platform Engineering팀/11ST <devmonster@11stcorp.com>
2021-11-10 15:11:33 +01:00
Juergen Hoeller 75036fa0ad Merge branch '5.3.x' 2021-11-10 14:22:58 +01:00
Juergen Hoeller 0e1ba7aae5 Merge branch '5.3.x'
# Conflicts:
#	build.gradle
#	spring-context/src/main/java/org/springframework/context/annotation/Lazy.java
2021-11-09 22:39:58 +01:00
Stephane Nicoll cd5657d158 Merge branch '5.3.x' 2021-11-09 19:39:57 +01:00
Sam Brannen 8de58f4f32 Merge branch '5.3.x' 2021-11-09 14:23:36 +01:00
Rossen Stoyanchev ec947065a9 Merge branch '5.3.x' into main 2021-11-09 10:23:14 +00:00
Juergen Hoeller 5acc3228f7 Upgrade to Hibernate ORM 5.6.1, Tomcat 10.0.12, Netty 4.1.70, HtmlUnit 2.54, XMLUnit 2.8.3 2021-11-08 17:42:02 +01:00
Sam Brannen ebfec822cb Merge branch '5.3.x' 2021-11-05 10:33:54 +01:00
Stephane Nicoll ea86b4d36c Merge branch '5.3.x' 2021-11-04 14:52:18 +01:00
Arjen Poutsma 1eb8c93689 Merge branch '5.3.x' 2021-11-03 15:03:31 +01:00
Arjen Poutsma a71f0eb267 Merge branch '5.3.x' 2021-11-02 16:21:16 +01:00
Sam Brannen 56fd97184c Avoid generic type parameter hiding in UnmodifiableValueCollection 2021-10-29 11:32:44 +02:00
Sam Brannen 4464468465 Clean up warnings in UnmodifiableMultiValueMapTests 2021-10-29 11:27:38 +02:00
Sam Brannen 32c14a2b42 Update Javadoc regarding repeatable annotation support 2021-10-29 11:04:01 +02:00
최유진(Yujin Choi)/Platform Engineering팀/11ST 8dd385b440 Use toUnmodifiableSet and toList instead of collectingAndThen
Since Spring Framework 6 uses JDK 17 for its baseline, we can make use
of toList() and toUnmodifiableSet() which were introduced in JDK 16 and
JDK 10, respectively.

Closes gh-27618
2021-10-28 16:37:41 +02:00
Stephane Nicoll 5ea1cf532e Merge branch '5.3.x' 2021-10-28 14:21:53 +02:00
Arjen Poutsma 0a9746e820 Merge branch '5.3.x' 2021-10-27 16:37:00 +02:00
Arjen Poutsma 0a58419df4 Add immutable MultiValueMap wrapper
This commit introduces UnmodifiableMultiValueMap, an immutable wrapper
around a MultiValueMap, similar to what is returned by
Collections.unmodifiable*.
CollectionUtils::unmodifiableMultiValueMap now returns
UnmodifiableMultiValueMap.

Closes gh-27608
2021-10-26 15:31:34 +02:00
Brian Clozel 6fd0615be9 Fix JDK18 declaration in CI pipeline
See gh-27607
2021-10-26 09:12:30 +02:00
Sam Brannen c989470f94 Remove unused code in FormattingConversionServiceTests
This commit removes test code that became obsolete with the removal of
Joda Time support.
2021-10-25 17:12:55 +02:00
Sam Brannen 267df1c0f2 Merge branch '5.3.x' 2021-10-25 17:07:29 +02:00
Sam Brannen 63697ca06d Merge branch '5.3.x' 2021-10-25 16:31:55 +02:00
Brian Clozel 683bdf2675 Polish JDK 18 CI pipeline
This commit ensures that JDK 18 is properly installed in the CI image.

See gh-27607
2021-10-25 10:06:06 +02:00
Brian Clozel 65bf5f7c81 Add JDK18 variant to CI pipeline
This commit adds a new JDK 18 variant to the CI build image and
configures a JDK18 build (sources compiled with JDK17, tests compiled
and run with JDK18) to the CI pipeline.

Closes gh-27607
2021-10-25 10:02:39 +02:00
Sam Brannen e4e667acdb Polishing 2021-10-23 18:02:55 +02:00
Sam Brannen 63509e64d4 Merge branch '5.3.x' 2021-10-23 17:47:55 +02:00
Sam Brannen 1e36518182 Merge branch '5.3.x' 2021-10-23 16:08:43 +02:00
Sam Brannen d9e9a33b66 Merge branch '5.3.x' 2021-10-22 15:29:37 +02:00
Sam Brannen c3650f3cd6 Merge branch '5.3.x' 2021-10-22 14:58:25 +02:00
Sam Brannen e9fc35495e Merge branch '5.3.x' 2021-10-22 14:36:43 +02:00
Sam Brannen bd55f609a7 Merge branch '5.3.x' 2021-10-22 14:01:57 +02:00
Sam Brannen 170d6dd5f2 Merge branch '5.3.x' 2021-10-22 13:17:59 +02:00
Sam Brannen 71036e7da5 Merge branch '5.3.x' 2021-10-21 14:16:24 +02:00
Sam Brannen 59beef71df Merge branch '5.3.x'
# Conflicts:
#	gradle.properties
2021-10-21 12:42:03 +02:00
Arjen Poutsma e4b493456b Remove custom EnumerationIterator
This commit removes our custom EnumerationIterator, in favor of
Enumeration::asIterator (since JDK 9).
2021-10-20 18:29:33 +02:00
Sam Brannen dd79be3664 Merge branch '5.3.x' 2021-10-20 14:49:17 +02:00
Sam Brannen 8e245e4410 Remove commented-out custom stylesheet for Javadoc
The team has decided to use the default Javadoc stylesheet with JDK 17.

Closes gh-27496
2021-10-20 13:07:45 +02:00
Sam Brannen f78d9cdf22 Remove configuration of obsolete html5 javadoc option 2021-10-19 16:58:36 +02:00
Sam Brannen fe8518dcb2 Merge branch '5.3.x' 2021-10-19 16:46:25 +02:00
Sam Brannen aa5a2a8600 Disable custom stylesheet for Javadoc
The custom stylesheet used with JDK 8 no longer works with JDK 17.

Thus in order to make the generated Javadoc usable, we are disabling
the custom stylesheet for the time being.

See gh-27496
2021-10-19 16:42:22 +02:00
Rossen Stoyanchev 22f75d9ea9 Merge branch '5.3.x' into main 2021-10-19 12:35:37 +01:00
Arjen Poutsma 9804e75051 Merge branch '5.3.x' 2021-10-19 11:59:53 +02:00
Rossen Stoyanchev b681c6b4bc Merge branch '5.3.x' into main 2021-10-18 17:08:55 +01:00
Rossen Stoyanchev 24b0035369 Merge branch '5.3.x' into main 2021-10-18 16:56:02 +01:00
Rossen Stoyanchev f01b856064 Merge branch '5.3.x' into main 2021-10-18 16:27:34 +01:00
Sam Brannen 3b531d9494 Merge branch '5.3.x' 2021-10-17 19:34:19 +02:00
Sam Brannen b51813e408 Apply "instanceof pattern matching" in spring-websocket
This commit also applies additional clean-up tasks such as the following.

- final fields
- diamond operator (<>) for anonymous inner classes

This has only been applied to `src/main/java`.
2021-10-17 19:04:32 +02:00
Sam Brannen 1f248b34f6 Apply "instanceof pattern matching" in spring-webmvc
This commit also applies additional clean-up tasks such as the following.

- final fields
- diamond operator (<>) for anonymous inner classes
- try with resources
- multi-catch

This has only been applied to `src/main/java`.
2021-10-17 18:49:02 +02:00
Sam Brannen 8135ae6d38 Apply "instanceof pattern matching" in spring-webflux
This commit also applies additional clean-up tasks such as the following.

- final fields
- diamond operator (<>) for anonymous inner classes
- multi-catch

This has only been applied to `src/main/java`.
2021-10-17 13:30:05 +02:00
Sam Brannen 785212d676 Apply "instanceof pattern matching" in spring-web
This commit also applies additional clean-up tasks such as the following.

- final fields
- diamond operator (<>) for anonymous inner classes
- try with resources

This has only been applied to `src/main/java`.
2021-10-17 12:58:25 +02:00
Sam Brannen e9cf645b86 Apply "instanceof pattern matching" in spring-tx
This commit also applies additional clean-up tasks such as the following.

- final fields

This has only been applied to `src/main/java`.
2021-10-14 22:18:01 +02:00
Sam Brannen b8fc79543d Polish tests and test fixtures in spring-test 2021-10-14 22:12:23 +02:00
Sam Brannen 9b4f3880b3 Apply "instanceof pattern matching" in spring-oxm
This has only been applied to `src/main/java`.
2021-10-14 22:08:40 +02:00
Sam Brannen 40ead013fa Apply "instanceof pattern matching" in spring-orm
This has only been applied to `src/main/java`.
2021-10-14 21:55:20 +02:00
Sam Brannen 1cd70bbe6b Apply "instanceof pattern matching" in spring-messaging
This commit also applies additional clean-up tasks such as the following.

- final fields
- diamond operator (<>) for anonymous inner classes
- for-each loop

This has only been applied to `src/main/java`.
2021-10-14 20:18:29 +02:00
Sam Brannen d70a610a0d Apply "instanceof pattern matching" in spring-jms
This commit also applies additional clean-up tasks such as the following.

- final fields

This has only been applied to `src/main/java`.
2021-10-14 19:59:38 +02:00
Sam Brannen 971f665eb1 Apply "instanceof pattern matching" in spring-jdbc
This commit also applies additional clean-up tasks such as the following.

- final fields

This has only been applied to `src/main/java`.
2021-10-14 19:55:14 +02:00
Sam Brannen 4e6ef82d8f Apply "instanceof pattern matching" in spring-expression
This commit also applies additional clean-up tasks such as the following.

- final fields

This commit also makes use of java.lang.String.repeat(int) in OptMultiply.

This has only been applied to `src/main/java`.
2021-10-14 19:46:21 +02:00
Sam Brannen cb17441780 Apply "instanceof pattern matching" Eclipse clean-up in spring-core
This commit also applies additional clean-up tasks such as the following.

- final fields
- diamond operator (<>) for anonymous inner classes

This has only been applied to `src/main/java`.
2021-10-14 18:30:06 +02:00
Rossen Stoyanchev 9b9906cfc4 Merge branch '5.3.x' into main 2021-10-14 17:22:29 +01:00
Sam Brannen b3473a3e81 Apply "instanceof pattern matching" Eclipse clean-up in spring-context-support
This has only been applied to `src/main/java`.
2021-10-14 17:45:56 +02:00
Sam Brannen 0eb73c130c Apply "instanceof pattern matching" Eclipse clean-up in spring-context-indexer 2021-10-14 17:33:53 +02:00
Sam Brannen 67333a3f94 Apply "instanceof pattern matching" Eclipse clean-up in spring-context
This commit also applies additional clean-up tasks such as the following.

- final fields
- diamond operator (<>) for anonymous inner classes
- Comparator.comparing
- convert to switch expression

This has only been applied to `src/main/java`.
2021-10-14 17:33:53 +02:00
Sam Brannen 401c0d220a Apply "instanceof pattern matching" Eclipse clean-up in spring-beans
This commit also applies additional clean-up tasks such as the following.

- final fields
- diamond operator (<>) for anonymous inner classes
- Comparator.comparing

This has only been applied to `src/main/java`.
2021-10-14 16:50:19 +02:00
Sam Brannen 63c6a7e15e Update copyright date 2021-10-14 16:26:21 +02:00
Sam Brannen 07cd6ab761 Apply "instanceof pattern matching" Eclipse clean-up in spring-aop
This commit also applies additional clean-up tasks such as the following.

- final fields

This has only been applied to `src/main/java`.
2021-10-14 16:13:50 +02:00
Sam Brannen fba92c0120 Update copyright date 2021-10-14 16:03:39 +02:00
Sam Brannen 940a37f9ce Apply "final fields" Eclipse clean-up in spring-test
This has only been applied to `src/main/java`.
2021-10-14 15:53:54 +02:00
Sam Brannen 7e4870577d Apply "instanceof pattern matching" Eclipse clean-up in spring-test
This has only been applied to `src/main/java`.
2021-10-14 15:50:36 +02:00
Sam Brannen 4fc359f75e Merge branch '5.3.x' 2021-10-14 15:19:56 +02:00
Juergen Hoeller d312c13721 Upgrade to Hibernate ORM 5.6 Final, RxJava 3.1.2, JRuby 9.3.1 2021-10-14 14:48:56 +02:00
Stephane Nicoll 8134fb7a7c Merge branch '5.3.x' 2021-10-14 12:02:59 +02:00
Rossen Stoyanchev 921701b48d Merge branch '5.3.x' into main 2021-10-14 09:43:29 +01:00
liuzhifei ca999fb38c fix Javadoc typo in PathMatchConfigurer#setUseSuffixPatternMatch 2021-10-14 09:40:49 +01:00
Rossen Stoyanchev 3633b2a24f Merge branch '5.3.x' into main 2021-10-13 21:22:34 +01:00
Sam Brannen 373b90d263 Simplify JsonPathExpectationsHelperTests with text blocks 2021-10-13 20:43:13 +02:00
Sam Brannen 1ef47fa369 Use instanceof pattern matching in select classes in spring-test 2021-10-13 20:41:49 +02:00
Sam Brannen 887ecffaa9 Merge branch '5.3.x' 2021-10-13 20:05:18 +02:00
Sam Brannen 49c8cb5a60 Merge branch '5.3.x' 2021-10-13 19:23:18 +02:00
Rossen Stoyanchev 28a497f3b3 Merge branch '5.3.x' into main 2021-10-13 14:58:07 +01:00
Sam Brannen 95da027397 Merge branch '5.3.x' 2021-10-13 14:03:23 +02:00
Koen Punt daf10d6c45 Include correct keyword in CookieAssertions failure messages
Closes gh-27550
2021-10-13 14:00:29 +02:00
Juergen Hoeller 627fc7612d Merge branch '5.3.x'
# Conflicts:
#	build.gradle
2021-10-13 13:06:44 +02:00
Rossen Stoyanchev a74031454c Merge branch '5.3.x' into main 2021-10-12 16:31:16 +01:00
Sam Brannen 8820c893e6 Add note about Groovy Tools not working in Eclipse 2021-09 with Java 17
Closes gh-27407
2021-10-12 17:23:55 +02:00
Juergen Hoeller da457abd5b Merge branch '5.3.x' 2021-10-12 15:19:40 +02:00
Rossen Stoyanchev 7957b9cc0f Merge branch '5.3.x' into main 2021-10-12 12:00:55 +01:00
Sam Brannen 87cb84b832 Merge branch '5.3.x' 2021-10-12 12:27:55 +02:00
Stephane Nicoll 276aa46a1c Polish 2021-10-11 16:22:30 +02:00
Stephane Nicoll d16574f807 Merge branch '5.3.x' 2021-10-11 16:21:14 +02:00
Sam Brannen f479668938 Merge branch '5.3.x' 2021-10-11 15:00:00 +02:00
Rossen Stoyanchev bd85cb8bac Merge branch '5.3.x' into main 2021-10-11 11:20:14 +01:00
Sam Brannen 1709d609c2 Merge branch '5.3.x' 2021-10-10 23:26:14 +02:00
Sam Brannen 22f0f9f3df Merge branch '5.3.x' 2021-10-08 21:31:03 +02:00
Juergen Hoeller 56eefe2a13 Merge branch '5.3.x' 2021-10-08 20:42:54 +02:00
Sam Brannen fa3a2dc981 Upgrade to AspectJ 1.9.8 RC1 for Java 17 support
See gh-27537
2021-10-08 19:33:30 +02:00
Rossen Stoyanchev f14bd50033 Prune empty method adapter classes 2021-10-08 18:20:09 +01:00
Rossen Stoyanchev e3b48c23dd Remove AsyncRestTemplate and related types 2021-10-08 17:59:53 +01:00
Sam Brannen 932291b867 Polishinig 2021-10-08 14:00:23 +02:00
Brian Clozel 6e92c4d674 Improve Questions section in CONTRIBUTING doc
Closes gh-27509
2021-10-08 11:08:38 +02:00
Rossen Stoyanchev ccb080f948 Merge branch '5.3.x' into main 2021-10-07 16:55:35 +01:00
Stephane Nicoll 942a5986a8 Merge branch '5.3.x' 2021-10-07 08:54:52 +02:00
Rossen Stoyanchev 6eaaf294f3 Merge branch '5.3.x' into main 2021-10-06 21:32:01 +01:00
Sam Brannen 359661df9d Merge branch '5.3.x' 2021-10-06 15:43:09 +02:00
Sam Brannen 2c583517cb Change Eclipse project source/target/compliance to JDK 17
See gh-27407
2021-10-06 12:51:44 +02:00
Sam Brannen 2d1e0d5e38 Merge branch '5.3.x' 2021-10-06 12:13:21 +02:00
Arjen Poutsma fb7eea9757 Merge branch '5.3.x' 2021-10-05 16:32:55 +02:00
Rossen Stoyanchev c1856d24e2 Merge branch '5.3.x' into main 2021-10-05 14:52:45 +01:00
Sam Brannen c25aefdb2b Merge branch '5.3.x' 2021-10-05 15:24:11 +02:00
Sam Brannen 381b7d035a Merge branch '5.3.x' 2021-10-05 14:55:22 +02:00
Sam Brannen dabe823a4a Merge branch '5.3.x' 2021-10-05 14:24:36 +02:00
Rossen Stoyanchev 837dd30661 Merge branch '5.3.x' into main 2021-10-05 12:16:42 +01:00
Stephane Nicoll a9418b613c Merge branch '5.3.x' 2021-10-03 07:10:29 +02:00
Juergen Hoeller 48eb51a22f Upgrade to Jackson 2.13 2021-10-02 12:38:26 +02:00
Juergen Hoeller 5766855514 Merge branch '5.3.x'
# Conflicts:
#	build.gradle
2021-10-02 12:20:58 +02:00
Juergen Hoeller 04eed155cd Upgrade to Hibernate ORM 5.6 CR1, JRuby 9.3, WebJars Locator 0.48, HtmlUnit 2.53 2021-10-01 14:52:27 +02:00
Sam Brannen 545b1a33c6 Merge branch '5.3.x' 2021-10-01 14:39:15 +02:00
Juergen Hoeller e314a79fb0 Merge branch '5.3.x'
# Conflicts:
#	spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java
2021-10-01 13:29:46 +02:00
Sam Brannen b452d1b41d Remove obsolete references to Ehcache 2.x from ref docs 2021-10-01 13:06:57 +02:00
Sam Brannen 543738ca58 Merge branch '5.3.x' 2021-10-01 12:52:25 +02:00
Sam Brannen 1b8a5051ca Merge branch '5.3.x' 2021-10-01 11:11:40 +02:00
Sam Brannen cb9246e481 Merge branch '5.3.x' 2021-10-01 10:36:28 +02:00
Juergen Hoeller ad873617d2 Note on ClassLoader.defineClass being used as a fallback only 2021-09-30 18:26:01 +02:00
Juergen Hoeller f6a392c5ae Merge branch '5.3.x' 2021-09-30 18:14:15 +02:00
Juergen Hoeller dc5807ea51 Merge branch '5.3.x'
# Conflicts:
#	spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java
2021-09-30 17:37:28 +02:00
Arjen Poutsma a4b74a320e Merge branch '5.3.x' 2021-09-30 17:12:41 +02:00
Arjen Poutsma 4f61e9cdee Merge branch '5.3.x' 2021-09-30 16:17:36 +02:00
Sam Brannen 167e538dd1 Link to Jakarta EE APIs instead of Java EE APIs 2021-09-29 17:19:19 +02:00
Sam Brannen 3e53e54b80 Remove external Javadoc links to Tiles and Ehcache
Support code for Apache Tiles and Ehcache has already been removed from
Spring Framework 6.0.

This commit therefore removes the configuration for external links to
these projects.
2021-09-29 17:17:13 +02:00
Sam Brannen 030ba52805 Merge branch '5.3.x' 2021-09-29 16:56:33 +02:00
Juergen Hoeller 3ad796e913 Keep getEffectiveAnnotatedParameter for user code compiled with javac 8 2021-09-29 09:56:29 +02:00
Juergen Hoeller ac5dc698e2 Update/remove outdated JPA and Hibernate version references
Closes gh-27487
2021-09-28 19:10:09 +02:00
Juergen Hoeller f32f04d841 Code cleanup on new baseline 2021-09-28 19:02:44 +02:00
Juergen Hoeller 4d7fa9a632 Merge branch '5.3.x'
# Conflicts:
#	spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java
2021-09-28 18:18:23 +02:00
Arjen Poutsma 1e6c0d2f7b Merge branch '5.3.x' 2021-09-28 15:00:33 +02:00
Sam Brannen 08bce08018 Use text blocks with JUnit Jupiter 5.8.1
See gh-27450
2021-09-28 14:20:31 +02:00
Sam Brannen 6337e08f2b Merge branch '5.3.x' 2021-09-28 14:03:06 +02:00
Sam Brannen 93efb20a53 Fix broken links in Javadoc
This commit removes several links that were broken due to the removal
of various APIs in 6.0.

See gh-27480
2021-09-28 13:34:33 +02:00
Sam Brannen 3dc84c2d92 Merge branch '5.3.x' 2021-09-28 11:48:50 +02:00
Sam Brannen 16bf39ea1b Merge branch '5.3.x' 2021-09-28 10:35:18 +02:00
Juergen Hoeller d483992177 Upgrade to Caffeine 3.0.4 and Vavr 0.10.4
Includes removal of unused Hessian dependency.
2021-09-27 18:30:09 +02:00
Juergen Hoeller b3f6d60dc9 Merge branch '5.3.x'
# Conflicts:
#	build.gradle
#	spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java
#	spring-core/src/test/java/org/springframework/core/ReactiveAdapterRegistryTests.java
#	src/docs/asciidoc/web-reactive.adoc
2021-09-27 17:26:26 +02:00
Juergen Hoeller e6112344d2 Remove support for RxJava 2.x as well
Includes realignment of Reactor adapter registration.

Closes gh-27443
2021-09-27 13:01:32 +02:00
Sam Brannen 30efa4d478 Change default driver in XStreamMarshaller from XppDriver to DomDriver
As explained in commit a247b83cd9, the
XppDriver from XStream relies on the XPP3 library which publishes
javax.xml.namespace.QName as part of its JAR. The QName type is also
published by the java.xml system module in modular JREs (i.e., Java 9
or higher).

This results in a split package between the unnamed module and the
java.xml system module, which the Java Language Specification defines
as illegal (see §6.5.5.2 and §7.4.3).

Most Java compilers do not currently enforce this rule; however, the
Eclipse compiler does. This makes it impossible to use spring-oxm out
of the box in the Eclipse IDE. In addition, if bug JDK-8215739 is fixed
in future versions of other JDK implementations, this rule will affect
any users using spring-oxm with those JDKs.

This commit therefore switches the default driver in XStreamMarshaller
from XppDriver to DomDriver. Users can naturally switch back to the
XppDriver if they wish, since the driver is configurable.

Closes gh-27464
2021-09-25 15:06:45 +02:00
Phillip Webb 50f2016293 Fix timezone specific failing test
Update `MvcNamespaceTests` so that the asserted time is in UTC.
2021-09-24 16:52:51 -07:00
Rossen Stoyanchev 693ab84347 Merge branch '5.3.x' into main 2021-09-24 15:59:26 +01:00
Juergen Hoeller f440fb8baf Unit tests for record binding
See gh-27437
2021-09-23 16:13:20 +02:00
Juergen Hoeller 0241c5ebb3 Merge branch '5.3.x'
# Conflicts:
#	spring-core/spring-core.gradle
2021-09-23 15:59:32 +02:00
Brian Clozel 66b15efa21 Upgrade CI image to JDK 17+35 2021-09-23 13:57:39 +02:00
Sam Brannen 6689b3cd70 Merge branch '5.3.x' 2021-09-22 22:21:04 +02:00
Sam Brannen a247b83cd9 Ensure projects can be imported into Eclipse IDE with JDK 17
Prior to this commit, the Spring Framework projects could not be
imported into Eclipse IDE when using JDK 17 to build the projects.

The primary obstacle is the fact that Eclipse enforces a strict
"no split packages between the unnamed module and a system module" rule
when building with a "modular JDK" (such as JDK 17).

Resources:

- https://bugs.eclipse.org/bugs/show_bug.cgi?id=536928
- https://bugs.openjdk.java.net/browse/JDK-8215739
- http://mail.openjdk.java.net/pipermail/jigsaw-dev/2018-December/014077.html
- https://stackoverflow.com/questions/51094274/eclipse-cant-find-xml-related-classes-after-switching-build-path-to-jdk-10/53824670#53824670

Since the bug (JDK-8215739) has not been fixed in OpenJDK, the strict
"no split packages" rule does not apply to the Java compiler used in
Spring Framework's Gradle build or the compiler in IntelliJ IDEA. Hence,
this issue only arrises when building the framework in Eclipse IDE.

This commit addresses this issue in the following affected projects.

- spring-oxm: removal of the dependency on XPP3 which publishes
    javax.xml.namespace.QName as part of the JAR. The QName type is
    also published by the java.xml JDK 17 system module. To make the
    tests pass, we have switched to using the DomDriver instead of the
    XppDriver in our XStream tests.

- spring-test: HtmlUnit has a transitive dependency on xml-apis which
    publishes several packages also published by java.xml JDK 17 system
    module. Thus, we have explicitly excluded the transitive dependency
    on xml-apis for our `optional` configuration.

See gh-27407
2021-09-22 16:22:27 +02:00
Sam Brannen b808b53bcc Remove unnecessary cast in ContentRequestMatchers 2021-09-22 16:06:58 +02:00
Juergen Hoeller 8f96ca4a2d Merge branch '5.3.x'
# Conflicts:
#	spring-context/spring-context.gradle
#	spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java
2021-09-21 17:47:27 +02:00
Juergen Hoeller 774583dfa7 Retain support for legacy PostConstruct/PreDestroy/Inject variants
Also removes JAX-WS support from CommonAnnotationBeanPostProcessor.

Closes gh-27444
See gh-27422
2021-09-21 17:07:42 +02:00
Sam Brannen 6976bf774b Merge branch '5.3.x' 2021-09-21 14:23:49 +02:00
Sam Brannen 0d4be7deb0 Merge branch '5.3.x' 2021-09-21 13:04:58 +02:00
Sam Brannen d6570fa2ac Merge branch '5.3.x' 2021-09-21 12:39:38 +02:00
Sam Brannen 7135051c55 Merge branch '5.3.x' 2021-09-21 12:16:37 +02:00
Sam Brannen 01d82ef0c6 Merge branch '5.3.x' 2021-09-21 12:11:52 +02:00
Sam Brannen 070d087dbc Reinstate -Werror for Groovy compilation
This commit partially reverts cf2429b0f0
in order to reinstate -Werror for Groovy compilation in spring-beans.

The `decorating` field in GroovyDynamicElementReader has been changed
from boolean to Boolean in order to avoid the JDK 17 deprecation warning
for use of `new Boolean(false)` which the Groovy compiler apparently
uses behind the scenes when compiling Groovy source code.
2021-09-21 11:30:30 +02:00
Sam Brannen 69a46a7296 Merge branch '5.3.x' 2021-09-21 10:49:31 +02:00
Juergen Hoeller 3beb074278 Remove support for RxJava 1.x
Also removes unnecessary flowPublisherPresent check on JDK 9+, depending on Reactor presence for its JDK Flow adapter instead.

Closes gh-27443
2021-09-21 09:13:06 +02:00
Sam Brannen 5ab789b310 Merge branch '5.3.x' 2021-09-20 14:55:23 +02:00
Sam Brannen cf46384887 Merge branch '5.3.x' 2021-09-20 14:44:36 +02:00
Rossen Stoyanchev 958eb0f964 Revert temporary exclusion of failing Jetty 11 tests
Closes gh-27424

This reverts commit 5eac8555d9.
2021-09-17 14:54:59 +01:00
Rossen Stoyanchev 01426481ea Enforce timeout in WebFlux multipart tests 2021-09-17 14:53:45 +01:00
Rossen Stoyanchev 8b5f5d9f65 Fix multipart request test with Jetty server
See gh-27424
2021-09-17 14:53:45 +01:00
Rossen Stoyanchev 853ab5d67b Fix Jetty 10+ test failure related to empty path handling
See gh-27424
2021-09-17 14:53:27 +01:00
Rossen Stoyanchev 513cc1576e Fix Jetty WebSocket test failures for WebFlux
See gh-27424
2021-09-17 14:53:17 +01:00
Rossen Stoyanchev 48875dc44f Fix Jetty WebSocket test failures
See gh-27424
2021-09-17 14:53:09 +01:00
Rossen Stoyanchev b732ff3495 Ensure mutable headers for Jetty WebFlux request
In Jetty 10, request headers are immutable, see
https://github.com/eclipse/jetty.project/pull/4777, but we need to
remove/hide forwarded headers when they have been used.

See gh-27424
2021-09-17 14:52:45 +01:00
Brian Clozel cce61c3918 Merge branch '5.3.x' 2021-09-17 15:30:16 +02:00
Sam Brannen 5eac8555d9 Temporarily exclude failing Jetty 11 tests
See gh-27424
2021-09-17 11:50:54 +02:00
Juergen Hoeller d84ca2ba90 Jakarta EE 9 migration
Upgrades many dependency declarations; removes old EJB 2.x support and outdated Servlet-based integrations (Commons FileUpload, FreeMarker JSP support, Tiles).

Closes gh-22093
Closes gh-25354
Closes gh-26185
Closes gh-27423
See gh-27424
2021-09-17 09:14:07 +02:00
Juergen Hoeller 5822f1bf85 Drop RPC-style remoting
Closes gh-27422
2021-09-17 08:59:58 +02:00
Juergen Hoeller 3c8724ba3d Remove JiBX support
Closes gh-27425
2021-09-17 08:58:52 +02:00
Juergen Hoeller b7b078d26e Remove Joda-Time support
Closes gh-27426
2021-09-17 08:58:40 +02:00
Juergen Hoeller b74e93807e Remove JDK 9 workarounds etc
See gh-17778
2021-09-17 08:58:19 +02:00
Sam Brannen e0a4b05142 Merge branch '5.3.x' 2021-09-16 14:11:44 +02:00
Brian Clozel 33cddef026 Upgrade Javadoc URLs for JDK 17 based build
Prior to this commit, the Javadoc task would fail on
`spring-context-indexer` and `spring-instrumentation`. It seems that
missing remote docs or HTTP redirects were failing the process.

This commit removes the missing published Javadocs and updates the
version for the JDK API.

See gh-17778
2021-09-15 18:45:15 +02:00
Brian Clozel 4e3d1fa4e9 Temporarily downgrade Java compat level for AspectJ classes
AspectJ doesn't support JDK17 language level (yet).
For the time being, this commit is downgrading the language level for
the aspectJ generated classes to 1.8.

See gh-27416
2021-09-15 16:20:48 +02:00
Juergen Hoeller cf2429b0f0 Remove support for deprecated Java SecurityManager (-> JDK 17 build compatibility)
Includes hard JDK 9+ API dependency in CGLIB ReflectUtils (Lookup.defineClass) and removal of OutputStream spy proxy usage (avoiding invalid Mockito proxy on JDK 17)

Closes gh-26901
2021-09-15 15:30:25 +02:00
Juergen Hoeller 0640da74bc Upgrade to Checkstyle 9.0, Groovy 3.0.9, Hibernate ORM 5.5.7
Includes downgrade of Kotlin language level to 1.8 (for KotlinScriptTemplateTests)
2021-09-15 15:26:13 +02:00
Brian Clozel f53bf8e9e1 Merge branch '5.3.x' 2021-09-15 14:44:39 +02:00
Sam Brannen 350d3e8b22 Update @since tag in code template to 6.0 2021-09-15 14:24:14 +02:00
Brian Clozel 09b233365f Update project version to 6.0.0-SNAPSHOT 2021-09-15 14:03:51 +02:00
Brian Clozel c0e479460e Switch CI pipeline to a JDK17 baseline
This commit introduces a new `spring-framework-6.0.x` CI pipeline with
JDK 17 baseline.

Note that Kotlin still uses a JDK11 baseline for now, this will be
addressed in gh-27413.

Closes gh-27409
2021-09-15 12:37:10 +02:00
2432 changed files with 35894 additions and 66886 deletions
+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=17.0.2-librca
+12 -8
View File
@@ -6,7 +6,7 @@ First off, thank you for taking the time to contribute! :+1: :tada:
* [Code of Conduct](#code-of-conduct)
* [How to Contribute](#how-to-contribute)
* [Discuss](#discuss)
* [Ask questions](#ask-questions)
* [Create an Issue](#create-an-issue)
* [Issue Lifecycle](#issue-lifecycle)
* [Submit a Pull Request](#submit-a-pull-request)
@@ -22,11 +22,10 @@ Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
### How to Contribute
#### Discuss
#### Ask questions
If you have a question, check Stack Overflow using
[this list of tags](https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-remoting+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux?tab=Newest).
Find an existing discussion, or start a new one if necessary.
[this list of tags](https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-remoting+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux?tab=Newest). Find an existing discussion, or start a new one if necessary.
If you believe there is an issue, search through
[existing issues](https://github.com/spring-projects/spring-framework/issues) trying a
@@ -39,14 +38,18 @@ decision.
Reporting an issue or making a feature request is a great way to contribute. Your feedback
and the conversations that result from it provide a continuous flow of ideas. However,
before creating a ticket, please take the time to [discuss and research](#discuss) first.
before creating a ticket, please take the time to [ask and research](#ask-questions) first.
If creating an issue after a discussion on Stack Overflow, please provide a description
If you create an issue after a discussion on Stack Overflow, please provide a description
in the issue instead of simply referring to Stack Overflow. The issue tracker is an
important place of record for design discussions and should be self-sufficient.
Once you're ready, create an issue on
[GitHub](https://github.com/spring-projects/spring-framework/issues).
Once you're ready, create an issue on [GitHub](https://github.com/spring-projects/spring-framework/issues).
Many issues are caused by subtle behavior, typos, and unintended configuration.
Creating a [Minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example)
(starting with https://start.spring.io for example) of the problem helps the team
quickly triage your issue and get to the core of the problem.
#### Issue Lifecycle
@@ -129,3 +132,4 @@ When making changes locally, execute `./gradlew asciidoctor` and then browse the
Asciidoctor also supports live editing. For more details see
[AsciiDoc Tooling](https://docs.asciidoctor.org/asciidoctor/latest/tooling/).
+68 -110
View File
@@ -1,10 +1,10 @@
plugins {
id 'io.spring.dependency-management' version '1.0.11.RELEASE' apply false
id 'io.spring.nohttp' version '0.0.10'
id "io.freefair.aspectj" version '6.2.0' apply false
id "io.freefair.aspectj" version '6.4.0' apply false
id 'org.jetbrains.dokka' version '1.6.10' apply false
id 'org.jetbrains.kotlin.jvm' version '1.5.32' apply false
id "org.jetbrains.kotlin.plugin.serialization" version "1.5.32" apply false
id 'org.jetbrains.kotlin.jvm' version '1.6.20-RC' apply false
id "org.jetbrains.kotlin.plugin.serialization" version '1.6.20-RC' apply false
id 'org.asciidoctor.jvm.convert' version '3.3.2'
id 'org.asciidoctor.jvm.pdf' version '3.3.2'
id "org.unbroken-dome.xjc" version '2.0.0' apply false
@@ -27,15 +27,15 @@ configure(allprojects) { project ->
dependencyManagement {
imports {
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.6"
mavenBom "com.fasterxml.jackson:jackson-bom:2.13.1"
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.r2dbc:r2dbc-bom:Borca-RELEASE"
mavenBom "io.rsocket:rsocket-bom:1.1.1"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.45.v20220203"
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.eclipse.jetty:jetty-bom:11.0.8"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.6.20-RC"
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.0"
mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.3.2"
mavenBom "org.junit:junit-bom:5.8.2"
}
dependencies {
@@ -51,27 +51,22 @@ configure(allprojects) { project ->
}
dependency "com.google.code.findbugs:jsr305:3.0.2"
dependencySet(group: 'org.aspectj', version: '1.9.7') {
dependencySet(group: 'org.aspectj', version: '1.9.8') {
entry 'aspectjrt'
entry 'aspectjtools'
entry 'aspectjweaver'
}
dependencySet(group: 'org.codehaus.groovy', version: '3.0.9') {
dependencySet(group: 'org.apache.groovy', version: '4.0.1') {
entry 'groovy'
entry 'groovy-jsr223'
entry 'groovy-templates' // requires findbugs for warning-free compilation
entry 'groovy-test'
entry 'groovy-xml'
}
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.projectreactor.tools:blockhound:1.0.6.RELEASE"
dependency "com.caucho:hessian:4.0.63"
dependency "com.fasterxml:aalto-xml:1.3.1"
dependency("com.fasterxml.woodstox:woodstox-core:6.2.8") {
exclude group: "stax", name: "stax-api"
@@ -79,26 +74,23 @@ 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.qdox:qdox:2.0.1"
dependency("com.thoughtworks.xstream:xstream:1.4.18") {
exclude group: "xpp3", name: "xpp3_min"
exclude group: "xmlpull", name: "xmlpull"
}
dependency "org.apache.johnzon:johnzon-jsonb:1.2.16"
dependency "org.eclipse:yasson:2.0.4"
dependency("org.codehaus.jettison:jettison:1.3.8") {
exclude group: "stax", name: "stax-api"
}
dependencySet(group: 'org.jibx', version: '1.3.3') {
entry 'jibx-bind'
entry 'jibx-run'
}
dependency "org.ogce:xpp3:1.1.6"
dependency "org.yaml:snakeyaml:1.30"
dependency "com.h2database:h2:2.1.210"
dependency "com.github.ben-manes.caffeine:caffeine:2.9.3"
dependency "com.github.ben-manes.caffeine:caffeine:3.0.5"
dependency "com.github.librepdf:openpdf:1.3.26"
dependency "com.rometools:rome:1.18.0"
dependency "commons-io:commons-io:2.5"
dependency "commons-io:commons-io:2.11.0"
dependency "io.vavr:vavr:0.10.4"
dependency "net.sf.jopt-simple:jopt-simple:5.0.4"
dependencySet(group: 'org.apache.activemq', version: '5.16.2') {
@@ -108,70 +100,57 @@ configure(allprojects) { project ->
}
entry 'activemq-stomp'
}
dependency "org.apache.bcel:bcel:6.0"
dependency "org.apache.commons:commons-pool2:2.9.0"
dependencySet(group: 'org.apache.derby', version: '10.14.2.0') {
entry 'derby'
entry 'derbyclient'
}
dependency "org.apache.poi:poi-ooxml:4.1.2"
dependency "org.apache.poi:poi-ooxml:5.2.0"
dependency "org.apache-extras.beanshell:bsh:2.0b6"
dependency "org.freemarker:freemarker:2.3.31"
dependency "org.hsqldb:hsqldb:2.5.2"
dependency "org.quartz-scheduler:quartz:2.3.2"
dependency "org.codehaus.fabric3.api:commonj:1.1.0"
dependency "net.sf.ehcache:ehcache:2.10.6"
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-core-jakarta:5.6.6.Final"
dependency "org.hibernate:hibernate-validator:7.0.4.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: '10.0.14') {
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: '10.0.14') {
entry 'tomcat-embed-core'
entry 'tomcat-embed-websocket'
}
dependencySet(group: 'io.undertow', version: '2.2.16.Final') {
entry 'undertow-core'
entry('undertow-servlet') {
exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_4.0_spec"
exclude group: "org.jboss.spec.javax.annotation", name: "jboss-annotations-api_1.3_spec"
}
entry('undertow-websockets-jsr') {
exclude group: "org.jboss.spec.javax.websocket", name: "jboss-websocket-api_1.1_spec"
}
entry 'undertow-servlet-jakarta'
entry 'undertow-websockets-jsr-jakarta'
}
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.10"
dependency "org.eclipse.jetty:jetty-reactive-httpclient:3.0.5"
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") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.apache.httpcomponents:httpasyncclient:4.1.5") {
exclude group: "commons-logging", name: "commons-logging"
}
dependencySet(group: 'com.squareup.okhttp3', version: '3.14.9') {
entry 'okhttp'
entry 'mockwebserver'
}
dependency "org.jruby:jruby:9.2.20.1"
dependency "org.jruby:jruby:9.3.3.0"
dependency "org.python:jython-standalone:2.7.1"
dependency "org.mozilla:rhino:1.7.11"
dependency "commons-fileupload:commons-fileupload:1.4"
dependency "org.synchronoss.cloud:nio-multipart-parser:1.1.0"
dependency("org.dom4j:dom4j:2.1.3") {
exclude group: 'javax.xml.bind', name: "jaxb-api"
exclude group: "jaxen", name: "jaxen"
exclude group: "net.java.dev.msv", name: "xsdlib"
exclude group: "pull-parser", name: "pull-parser"
@@ -220,68 +199,47 @@ configure(allprojects) { project ->
dependency "com.jayway.jsonpath:json-path:2.6.0"
dependency "org.bouncycastle:bcpkix-jdk15on:1.66"
dependencySet(group: 'org.apache.tiles', version: '3.0.8') {
entry 'tiles-api'
entry('tiles-core', withoutJclOverSlf4j)
entry('tiles-servlet', withoutJclOverSlf4j)
entry('tiles-jsp', withoutJclOverSlf4j)
entry('tiles-el', withoutJclOverSlf4j)
entry('tiles-extras') {
exclude group: "org.springframework", name: "spring-web"
exclude group: "org.slf4j", name: "jcl-over-slf4j"
}
}
dependency("org.apache.taglibs:taglibs-standard-jstlel:1.2.5") {
exclude group: "org.apache.taglibs", name: "taglibs-standard-spec"
}
dependency "javax.cache:cache-api:1.1.1"
dependency "javax.money:money-api:1.1"
dependency "org.javamoney:moneta:1.4.2"
dependency "com.ibm.websphere:uow:6.0.2.17"
dependency "com.jamonapi:jamon:2.82"
dependency "joda-time:joda-time:2.10.13"
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.10"
dependency "org.javamoney:moneta:1.3"
dependency "jakarta.activation:jakarta.activation-api:2.0.1"
dependency "jakarta.annotation:jakarta.annotation-api:2.0.0"
dependency "jakarta.ejb:jakarta.ejb-api:4.0.0"
dependency "jakarta.el:jakarta.el-api:4.0.0"
dependency "jakarta.enterprise.concurrent:jakarta.enterprise.concurrent-api:2.0.0"
dependency "jakarta.faces:jakarta.faces-api:3.0.0"
dependency "jakarta.inject:jakarta.inject-api:2.0.0"
dependency "jakarta.inject:jakarta.inject-tck:2.0.1"
dependency "jakarta.interceptor:jakarta.interceptor-api:2.0.0"
dependency "jakarta.jms:jakarta.jms-api:3.0.0"
dependency "jakarta.json:jakarta.json-api:2.0.1"
dependency "jakarta.json.bind:jakarta.json.bind-api:2.0.0"
dependency "jakarta.mail:jakarta.mail-api:2.0.1"
dependency "jakarta.persistence:jakarta.persistence-api:3.0.0"
dependency "jakarta.resource:jakarta.resource-api:2.0.0"
dependency "jakarta.servlet:jakarta.servlet-api:5.0.0"
dependency "jakarta.servlet.jsp:jakarta.servlet.jsp-api:3.0.0"
dependency "jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:2.0.0"
dependency "jakarta.transaction:jakarta.transaction-api:2.0.0"
dependency "jakarta.validation:jakarta.validation-api:3.0.0"
dependency "jakarta.websocket:jakarta.websocket-api:2.0.0"
dependency "jakarta.xml.bind:jakarta.xml.bind-api:3.0.1"
dependency "com.sun.activation:javax.activation:1.2.0"
dependency "com.sun.mail:javax.mail:1.6.2"
dependencySet(group: 'com.sun.xml.bind', version: '2.3.0.1') {
dependency "com.sun.activation:jakarta.activation:2.0.1"
dependency "com.sun.mail:jakarta.mail:2.0.1"
dependencySet(group: 'com.sun.xml.bind', version: '3.0.2') {
entry 'jaxb-core'
entry 'jaxb-impl'
entry 'jaxb-xjc'
}
dependency "javax.activation:javax.activation-api:1.2.0"
dependency "javax.annotation:javax.annotation-api:1.3.2"
dependency "javax.cache:cache-api:1.1.0"
dependency "javax.ejb:javax.ejb-api:3.2"
dependency "javax.el:javax.el-api:3.0.1-b04"
dependency "javax.enterprise.concurrent:javax.enterprise.concurrent-api:1.0"
dependency "javax.faces:javax.faces-api:2.2"
dependency "javax.inject:javax.inject:1"
dependency "javax.inject:javax.inject-tck:1"
dependency "javax.interceptor:javax.interceptor-api:1.2.2"
dependency "javax.jms:javax.jms-api:2.0.1"
dependency "javax.json:javax.json-api:1.1.4"
dependency "javax.json.bind:javax.json.bind-api:1.0"
dependency "javax.mail:javax.mail-api:1.6.2"
dependency "javax.money:money-api:1.0.3"
dependency "javax.resource:javax.resource-api:1.7.1"
dependency "javax.servlet:javax.servlet-api:4.0.1"
dependency "javax.servlet.jsp:javax.servlet.jsp-api:2.3.2-b02"
dependency "javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:1.2.1"
dependency "javax.transaction:javax.transaction-api:1.3"
dependency "javax.validation:validation-api:2.0.1.Final"
dependency "javax.websocket:javax.websocket-api:1.1"
dependency "javax.xml.bind:jaxb-api:2.3.1"
dependency "javax.xml.ws:jaxws-api:2.3.1"
dependency "org.eclipse.persistence:javax.persistence:2.2.0"
// Substitute for "javax.management:jmxremote_optional:1.0.1_04" which
// is not available on Maven Central
dependency "org.glassfish.external:opendmk_jmxremote_optional_jar:1.0-b01-ea"
dependency "org.glassfish:javax.el:3.0.1-b08"
dependency "org.glassfish.main:javax.jws:4.0-b33"
dependency "org.glassfish.tyrus:tyrus-container-servlet:1.13.1"
dependency "org.glassfish:jakarta.el:4.0.2"
dependency "org.glassfish.tyrus:tyrus-container-servlet:2.0.1"
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:3.0.2"
}
generatedPomCustomization {
enabled = false
@@ -318,15 +276,15 @@ configure([rootProject] + javaProjects) { project ->
compileKotlin {
kotlinOptions {
languageVersion = "1.3"
apiVersion = "1.3"
freeCompilerArgs = ["-Xjsr305=strict", "-Xsuppress-version-warnings", "-Xopt-in=kotlin.RequiresOptIn"]
languageVersion = "1.6"
apiVersion = "1.6"
freeCompilerArgs = ["-Xjsr305=strict", "-Xsuppress-version-warnings", "-opt-in=kotlin.RequiresOptIn"]
allWarningsAsErrors = true
}
}
compileTestKotlin {
kotlinOptions {
freeCompilerArgs = ["-Xjsr305=strict"]
freeCompilerArgs = ["-Xjsr305=strict", "-opt-in=kotlin.RequiresOptIn"]
}
}
}
@@ -366,16 +324,13 @@ configure([rootProject] + javaProjects) { project ->
}
ext.javadocLinks = [
"https://docs.oracle.com/javase/8/docs/api/",
"https://docs.oracle.com/javaee/7/api/",
"https://docs.oracle.com/en/java/javase/17/docs/api/",
"https://jakarta.ee/specifications/platform/9/apidocs/",
"https://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ
"https://www.ibm.com/docs/api/v1/content/SSEQTP_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/",
"https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/",
"https://docs.jboss.org/jbossas/javadoc/7.1.2.Final/",
"https://tiles.apache.org/tiles-request/apidocs/",
"https://tiles.apache.org/framework/apidocs/",
"https://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/",
"https://www.ehcache.org/apidocs/2.10.4/",
"https://www.quartz-scheduler.org/api/2.3.0/",
"https://fasterxml.github.io/jackson-core/javadoc/2.10/",
"https://fasterxml.github.io/jackson-databind/javadoc/2.10/",
@@ -383,12 +338,15 @@ configure([rootProject] + javaProjects) { project ->
"https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/",
"https://projectreactor.io/docs/test/release/api/",
"https://junit.org/junit4/javadoc/4.13.2/",
// Disabling linking to JUnit 5.8.2, since the `package-list` file no longer exists due to
// https://github.com/junit-team/junit5/commit/67ad4e545518b0ce2b0e7c96df31a669866d5003.
// TODO Uncomment link to JUnit 5 docs once we have sorted out
// the following warning in the build.
//
// warning: The code being documented uses packages in the unnamed module, but the packages defined in https://junit.org/junit5/docs/5.8.1/api/ are in named modules.
//
// "https://junit.org/junit5/docs/5.8.2/api/",
"https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/",
"https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/",
"https://r2dbc.io/spec/0.8.5.RELEASE/api/",
"https://r2dbc.io/spec/0.9.1.RELEASE/api/",
// The external Javadoc link for JSR 305 must come last to ensure that types from
// JSR 250 (such as @PostConstruct) are still supported. This is due to the fact
// that JSR 250 and JSR 305 both define types in javax.annotation, which results
@@ -16,6 +16,7 @@
package org.springframework.build.api;
import java.io.File;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
@@ -23,10 +24,14 @@ import java.util.List;
import me.champeau.gradle.japicmp.JapicmpPlugin;
import me.champeau.gradle.japicmp.JapicmpTask;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.artifacts.repositories.ArtifactRepository;
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
import org.gradle.api.artifacts.repositories.RepositoryContentDescriptor;
import org.gradle.api.plugins.JavaBasePlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin;
@@ -52,6 +57,8 @@ public class ApiDiffPlugin implements Plugin<Project> {
private static final List<String> PACKAGE_INCLUDES = Collections.singletonList("org.springframework.*");
private static final URI SPRING_MILESTONE_REPOSITORY = URI.create("https://repo.spring.io/milestone");
@Override
public void apply(Project project) {
if (project.hasProperty(BASELINE_VERSION_PROPERTY) && project.equals(project.getRootProject())) {
@@ -68,6 +75,10 @@ public class ApiDiffPlugin implements Plugin<Project> {
private void createApiDiffTask(String baselineVersion, Project project) {
if (isProjectEligible(project)) {
// Add Spring Milestone repository for generating diffs against previous milestones
project.getRootProject()
.getRepositories()
.maven(mavenArtifactRepository -> mavenArtifactRepository.setUrl(SPRING_MILESTONE_REPOSITORY));
JapicmpTask apiDiff = project.getTasks().create(TASK_NAME, JapicmpTask.class);
apiDiff.setDescription("Generates an API diff report with japicmp");
apiDiff.setGroup(JavaBasePlugin.DOCUMENTATION_GROUP);
@@ -24,7 +24,6 @@ import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.plugins.JavaLibraryPlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.compile.JavaCompile;
/**
@@ -70,7 +69,6 @@ public class CompilerConventionsPlugin implements Plugin<Project> {
* @param project the current project
*/
private void applyJavaCompileConventions(Project project) {
JavaPluginConvention java = project.getConvention().getPlugin(JavaPluginConvention.class);
project.getTasks().withType(JavaCompile.class)
.matching(compileTask -> compileTask.getName().equals(JavaPlugin.COMPILE_JAVA_TASK_NAME))
.forEach(compileTask -> {
@@ -19,12 +19,9 @@ package org.springframework.build.optional;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.attributes.Usage;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.plugins.JavaPluginExtension;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.plugins.ide.eclipse.EclipsePlugin;
import org.gradle.plugins.ide.eclipse.model.EclipseModel;
/**
* A {@code Plugin} that adds support for Maven-style optional dependencies. Creates a new
@@ -47,7 +44,7 @@ public class OptionalDependenciesPlugin implements Plugin<Project> {
optional.setCanBeConsumed(false);
optional.setCanBeResolved(false);
project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> {
SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class)
SourceSetContainer sourceSets = project.getExtensions().getByType(JavaPluginExtension.class)
.getSourceSets();
sourceSets.all((sourceSet) -> {
project.getConfigurations().getByName(sourceSet.getCompileClasspathConfigurationName()).extendsFrom(optional);
+2 -2
View File
@@ -2,7 +2,7 @@
The Spring Framework uses https://concourse-ci.org/[Concourse] for its CI build and other automated tasks.
The Spring team has a dedicated Concourse instance available at https://ci.spring.io with a build pipeline
for https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.3.x[Spring Framework 5.3.x].
for https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-6.0.x[Spring Framework 6.0.x].
=== Setting up your development environment
@@ -51,7 +51,7 @@ The pipeline can be deployed using the following command:
[source]
----
$ fly -t spring set-pipeline -p spring-framework-5.3.x -c ci/pipeline.yml -l ci/parameters.yml
$ fly -t spring set-pipeline -p spring-framework-6.0.x -c ci/pipeline.yml -l ci/parameters.yml
----
NOTE: This assumes that you have credhub integration configured with the appropriate secrets.
+3 -3
View File
@@ -2,10 +2,10 @@ FROM ubuntu:focal-20220302
ADD setup.sh /setup.sh
ADD get-jdk-url.sh /get-jdk-url.sh
RUN ./setup.sh java8
RUN ./setup.sh
ENV JAVA_HOME /opt/openjdk/java8
ENV JDK11 /opt/openjdk/java11
ENV JAVA_HOME /opt/openjdk/java17
ENV JDK17 /opt/openjdk/java17
ENV JDK18 /opt/openjdk/java18
ENV PATH $JAVA_HOME/bin:$PATH
+3 -9
View File
@@ -2,19 +2,13 @@
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"
;;
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"
;;
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"
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"
;;
*)
echo $"Unknown java version"
exit 1
echo $"Unknown java version"
exit 1
esac
+1 -1
View File
@@ -22,7 +22,7 @@ curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/
mkdir -p /opt/openjdk
pushd /opt/openjdk > /dev/null
for jdk in java8 java11 java17
for jdk in java17 java18
do
JDK_URL=$( /get-jdk-url.sh $jdk )
mkdir $jdk
+2 -2
View File
@@ -2,8 +2,8 @@ github-repo: "https://github.com/spring-projects/spring-framework.git"
github-repo-name: "spring-projects/spring-framework"
docker-hub-organization: "springci"
artifactory-server: "https://repo.spring.io"
branch: "5.3.x"
milestone: "5.3.x"
branch: "main"
milestone: "6.0.x"
build-name: "spring-framework"
pipeline-name: "spring-framework"
concourse-url: "https://ci.spring.io"
+22 -58
View File
@@ -72,13 +72,6 @@ resources:
icon: github
source:
<<: *git-repo-resource-source
- name: every-morning
type: time
icon: alarm
source:
start: 8:00 AM
stop: 9:00 AM
location: Europe/Vienna
- name: ci-images-git-repo
type: git
icon: github
@@ -92,6 +85,13 @@ resources:
source:
<<: *docker-resource-source
repository: ((docker-hub-organization))/spring-framework-ci
- name: every-morning
type: time
icon: alarm
source:
start: 8:00 AM
stop: 9:00 AM
location: Europe/Vienna
- name: artifactory-repo
type: artifactory-resource
icon: package-variant
@@ -116,22 +116,14 @@ resources:
access_token: ((github-ci-status-token))
branch: ((branch))
context: build
- name: repo-status-jdk11-build
- name: repo-status-jdk18-build
type: github-status-resource
icon: eye-check-outline
source:
repository: ((github-repo-name))
access_token: ((github-ci-status-token))
branch: ((branch))
context: jdk11-build
- name: repo-status-jdk17-build
type: github-status-resource
icon: eye-check-outline
source:
repository: ((github-repo-name))
access_token: ((github-ci-status-token))
branch: ((branch))
context: jdk17-build
context: jdk18-build
- name: slack-alert
type: slack-notification
icon: slack
@@ -221,35 +213,7 @@ jobs:
"zip.type": "schema"
get_params:
threads: 8
- name: jdk11-build
serial: true
public: true
plan:
- get: ci-image
- get: git-repo
- get: every-morning
trigger: true
- put: repo-status-jdk11-build
params: { state: "pending", commit: "git-repo" }
- do:
- task: check-project
image: ci-image
file: git-repo/ci/tasks/check-project.yml
privileged: true
timeout: ((task-timeout))
params:
TEST_TOOLCHAIN: 11
<<: *build-project-task-params
on_failure:
do:
- put: repo-status-jdk11-build
params: { state: "failure", commit: "git-repo" }
- put: slack-alert
params:
<<: *slack-fail-params
- put: repo-status-jdk11-build
params: { state: "success", commit: "git-repo" }
- name: jdk17-build
- name: jdk18-build
serial: true
public: true
plan:
@@ -257,25 +221,25 @@ jobs:
- get: git-repo
- get: every-morning
trigger: true
- put: repo-status-jdk17-build
- put: repo-status-jdk18-build
params: { state: "pending", commit: "git-repo" }
- do:
- task: check-project
image: ci-image
file: git-repo/ci/tasks/check-project.yml
privileged: true
timeout: ((task-timeout))
params:
TEST_TOOLCHAIN: 15
<<: *build-project-task-params
- task: check-project
image: ci-image
file: git-repo/ci/tasks/check-project.yml
privileged: true
timeout: ((task-timeout))
params:
TEST_TOOLCHAIN: 18
<<: *build-project-task-params
on_failure:
do:
- put: repo-status-jdk17-build
- put: repo-status-jdk18-build
params: { state: "failure", commit: "git-repo" }
- put: slack-alert
params:
<<: *slack-fail-params
- put: repo-status-jdk17-build
- put: repo-status-jdk18-build
params: { state: "success", commit: "git-repo" }
- name: build-pull-requests
serial: true
@@ -458,7 +422,7 @@ jobs:
groups:
- name: "builds"
jobs: ["build", "jdk11-build", "jdk17-build"]
jobs: ["build", "jdk18-build"]
- name: "releases"
jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release"]
- name: "ci-images"
+1 -1
View File
@@ -4,6 +4,6 @@ set -e
source $(dirname $0)/common.sh
pushd git-repo > /dev/null
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Porg.gradle.java.installations.fromEnv=JDK11,JDK15 \
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Porg.gradle.java.installations.fromEnv=JDK17,JDK18 \
-PmainToolchain=${MAIN_TOOLCHAIN} -PtestToolchain=${TEST_TOOLCHAIN} --no-daemon --max-workers=4 check
popd > /dev/null
+1 -1
View File
@@ -7,7 +7,7 @@ group = "org.springframework"
dependencies {
constraints {
parent.moduleProjects.sort { "$it.name" }.each {
parent.moduleProjects.findAll{ it.name != 'spring-core-test' }.sort{ "$it.name" }.each {
api it
}
}
+3 -3
View File
@@ -1,5 +1,5 @@
version=5.3.17-SNAPSHOT
org.gradle.jvmargs=-Xmx1536M
version=6.0.0-M3
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
@@ -20,7 +20,7 @@ tasks.findByName("dokkaHtmlPartial")?.configure {
url.set(new URL("https://javadoc.io/doc/org.hamcrest/hamcrest/2.1/"))
}
externalDocumentationLink {
url.set(new URL("https://javadoc.io/doc/javax.servlet/javax.servlet-api/latest/"))
url.set(new URL("https://javadoc.io/doc/jakarta.servlet/jakarta.servlet-api/latest/"))
}
externalDocumentationLink {
url.set(new URL("https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/"))
+1 -5
View File
@@ -43,14 +43,10 @@ task api(type: Javadoc) {
header = rootProject.description
use = true
overview = "src/docs/api/overview.html"
stylesheetFile = file("src/docs/api/stylesheet.css")
splitIndex = true
links(project.ext.javadocLinks)
addBooleanOption('Xdoclint:syntax', true) // only check syntax with doclint
addBooleanOption('Xwerror', true) // fail build on Javadoc warnings
if (JavaVersion.current().isJava9Compatible()) {
addBooleanOption('html5', true)
}
addBooleanOption('Werror', true) // fail build on Javadoc warnings
}
source moduleProjects.collect { project ->
project.sourceSets.main.allJava
+2 -2
View File
@@ -4,8 +4,8 @@ import org.gradle.plugins.ide.eclipse.model.SourceFolder
apply plugin: 'eclipse'
eclipse.jdt {
sourceCompatibility = 1.8
targetCompatibility = 1.8
sourceCompatibility = 17
targetCompatibility = 17
}
// Replace classpath entries with project dependencies (GRADLE-1116)
+21 -60
View File
@@ -5,13 +5,13 @@
* One can choose the toolchain to use for compiling the MAIN sources and/or compiling
* and running the TEST sources. These options apply to Java, Kotlin and Groovy sources
* when available.
* {@code "./gradlew check -PmainToolchain=8 -PtestToolchain=11"} will use:
* {@code "./gradlew check -PmainToolchain=17 -PtestToolchain=18"} will use:
* <ul>
* <li>a JDK8 toolchain for compiling the main SourceSet
* <li>a JDK11 toolchain for compiling and running the test SourceSet
* <li>a JDK17 toolchain for compiling the main SourceSet
* <li>a JDK18 toolchain for compiling and running the test SourceSet
* </ul>
*
* By default, the build will fall back to using the current JDK and 1.8 language level for all sourceSets.
* By default, the build will fall back to using the current JDK and 17 language level for all sourceSets.
*
* Gradle will automatically detect JDK distributions in well-known locations.
* The following command will list the detected JDKs on the host.
@@ -21,11 +21,11 @@
*
* We can also configure ENV variables and let Gradle know about them:
* {@code
* $ echo JDK11
* /opt/openjdk/java11
* $ echo JDK15
* /opt/openjdk/java15
* $ ./gradlew -Porg.gradle.java.installations.fromEnv=JDK11,JDK15 check
* $ echo JDK17
* /opt/openjdk/java17
* $ echo JDK18
* /opt/openjdk/java18
* $ ./gradlew -Porg.gradle.java.installations.fromEnv=JDK17,JDK18 check
* }
*
* @author Brian Clozel
@@ -44,7 +44,7 @@ def mainToolchainLanguageVersion() {
if (mainToolchainConfigured()) {
return JavaLanguageVersion.of(project.mainToolchain.toString())
}
return JavaLanguageVersion.of(8)
return JavaLanguageVersion.of(17)
}
def testToolchainLanguageVersion() {
@@ -64,9 +64,9 @@ plugins.withType(JavaPlugin) {
}
}
else {
// Fallback to JDK8
// Fallback to JDK17
java {
sourceCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_17
}
}
// Configure a specific Java Toolchain for compiling and running tests if the 'testToolchain' property is defined
@@ -86,63 +86,24 @@ plugins.withType(JavaPlugin) {
}
plugins.withType(GroovyPlugin) {
// Fallback to JDK8
// Fallback to JDK17
if (!mainToolchainConfigured()) {
compileGroovy {
sourceCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_17
}
}
}
pluginManager.withPlugin("kotlin") {
// Configure the Kotlin compiler if the 'mainToolchain' property is defined
if (mainToolchainConfigured()) {
def mainLanguageVersion = mainToolchainLanguageVersion()
def compiler = javaToolchains.compilerFor {
languageVersion = mainLanguageVersion
}
// See https://kotlinlang.org/docs/gradle.html#attributes-specific-for-jvm
def javaVersion = mainLanguageVersion.toString() == '8' ? '1.8' : mainLanguageVersion.toString()
compileKotlin {
kotlinOptions {
jvmTarget = javaVersion
jdkHome = compiler.get().metadata.installationPath.asFile.absolutePath
}
}
// Compile the test classes with the same version, 'testToolchain' will override if defined
compileTestKotlin {
kotlinOptions {
jvmTarget = javaVersion
jdkHome = compiler.get().metadata.installationPath.asFile.absolutePath
}
// Fallback to JDK17
compileKotlin {
kotlinOptions {
jvmTarget = '17'
}
}
else {
// Fallback to JDK8
compileKotlin {
kotlinOptions {
jvmTarget = '1.8'
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = '1.8'
}
}
}
if (testToolchainConfigured()) {
def testLanguageVersion = testToolchainLanguageVersion()
def compiler = javaToolchains.compilerFor {
languageVersion = testLanguageVersion
}
// See https://kotlinlang.org/docs/gradle.html#attributes-specific-for-jvm
def javaVersion = testLanguageVersion.toString() == '8' ? '1.8' : testLanguageVersion.toString()
compileTestKotlin {
kotlinOptions {
jvmTarget = javaVersion
jdkHome = compiler.get().metadata.installationPath.asFile.absolutePath
}
compileTestKotlin {
kotlinOptions {
jvmTarget = '17'
}
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+5 -4
View File
@@ -3,7 +3,7 @@
This document will guide you through the process of importing the Spring Framework
projects into Eclipse or the Spring Tool Suite (_STS_). It is recommended that you
have a recent version of Eclipse. As a bare minimum you will need Eclipse with full Java
8 support, Eclipse Buildship, and the Groovy plugin.
17 support and Eclipse Buildship.
The following instructions have been tested against [STS](https://spring.io/tools) 4.12.0
([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-4120-changelog))
@@ -12,13 +12,14 @@ The instructions should work with the latest Eclipse distribution as long as you
[Buildship](https://marketplace.eclipse.org/content/buildship-gradle-integration). Note
that STS 4 comes with Buildship preinstalled.
If you are using Eclipse 4.21, you will need to install
[Java 17 Support for Eclipse 2021-09 (4.21)](https://marketplace.eclipse.org/content/java-17-support-eclipse-2021-09-421)
from the Eclipse Marketplace.
## Steps
_When instructed to execute `./gradlew` from the command line, be sure to execute it within your locally cloned `spring-framework` working directory._
1. Install the [Groovy Development Tools](https://marketplace.eclipse.org/content/groovy-development-tools).
1. Switch to Groovy 3.0 in Eclipse (Preferences &#8594; Groovy &#8594; Compiler &#8594; Switch to 3.0...).
- If you encounter build errors stating something similar to _"Groovy: compiler mismatch: project level is 2.5, workspace level is 3.0"_, change the Groovy compiler version to 3.0 for each affected project.
1. Ensure that the _Forbidden reference (access rule)_ in Eclipse is set to `Info`
(Preferences &#8594; Java &#8594; Compiler &#8594; Errors/Warnings &#8594; Deprecated and restricted API &#8594; Forbidden reference (access rule)).
1. Optionally install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) if you need to execute Kotlin-based tests or develop Kotlin extensions.
+4 -4
View File
@@ -15,12 +15,12 @@ dependencies {
testImplementation(project(":spring-test"))
testImplementation(project(":spring-tx"))
testImplementation(project(":spring-web"))
testImplementation("javax.inject:javax.inject")
testImplementation("javax.resource:javax.resource-api")
testImplementation("javax.servlet:javax.servlet-api")
testImplementation("jakarta.inject:jakarta.inject-api")
testImplementation("jakarta.resource:jakarta.resource-api")
testImplementation("jakarta.servlet:jakarta.servlet-api")
testImplementation("org.aspectj:aspectjweaver")
testImplementation("org.hsqldb:hsqldb")
testImplementation("org.hibernate:hibernate-core")
testImplementation("org.hibernate:hibernate-core-jakarta")
}
normalization {
@@ -20,8 +20,7 @@ import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
import javax.servlet.ServletException;
import jakarta.servlet.ServletException;
import org.junit.jupiter.api.Test;
import org.springframework.aop.support.AopUtils;
@@ -21,9 +21,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Named;
import javax.inject.Singleton;
import jakarta.inject.Named;
import jakarta.inject.Singleton;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -308,19 +307,18 @@ class ClassPathBeanDefinitionScannerJsr330ScopeIntegrationTests {
scanner.setIncludeAnnotationConfig(false);
scanner.setScopeMetadataResolver(definition -> {
ScopeMetadata metadata = new ScopeMetadata();
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
if (definition instanceof AnnotatedBeanDefinition annDef) {
for (String type : annDef.getMetadata().getAnnotationTypes()) {
if (type.equals(javax.inject.Singleton.class.getName())) {
if (type.equals(jakarta.inject.Singleton.class.getName())) {
metadata.setScopeName(BeanDefinition.SCOPE_SINGLETON);
break;
}
else if (annDef.getMetadata().getMetaAnnotationTypes(type).contains(javax.inject.Scope.class.getName())) {
else if (annDef.getMetadata().getMetaAnnotationTypes(type).contains(jakarta.inject.Scope.class.getName())) {
metadata.setScopeName(type.substring(type.length() - 13, type.length() - 6).toLowerCase());
metadata.setScopedProxyMode(scopedProxyMode);
break;
}
else if (type.startsWith("javax.inject")) {
else if (type.startsWith("jakarta.inject")) {
metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE);
}
}
@@ -387,14 +385,14 @@ class ClassPathBeanDefinitionScannerJsr330ScopeIntegrationTests {
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@javax.inject.Scope
@jakarta.inject.Scope
public @interface RequestScoped {
}
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@javax.inject.Scope
@jakarta.inject.Scope
public @interface SessionScoped {
}
@@ -41,9 +41,6 @@ import org.springframework.context.support.GenericApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jca.context.ResourceAdapterApplicationContext;
import org.springframework.jca.support.SimpleBootstrapContext;
import org.springframework.jca.work.SimpleTaskWorkManager;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.mock.env.MockPropertySource;
import org.springframework.mock.web.MockServletConfig;
@@ -535,22 +532,6 @@ public class EnvironmentSystemIntegrationTests {
assertThat(environment.getProperty("pSysProps1")).isEqualTo("pSysProps1Value");
}
@Test
void resourceAdapterApplicationContext() {
ResourceAdapterApplicationContext ctx = new ResourceAdapterApplicationContext(new SimpleBootstrapContext(new SimpleTaskWorkManager()));
assertHasStandardEnvironment(ctx);
registerEnvironmentBeanDefinition(ctx);
ctx.setEnvironment(prodEnv);
ctx.refresh();
assertHasEnvironment(ctx, prodEnv);
assertEnvironmentBeanRegistered(ctx);
assertEnvironmentAwareInvoked(ctx, prodEnv);
}
@Test
void abstractApplicationContextValidatesRequiredPropertiesOnRefresh() {
{
@@ -41,7 +41,7 @@
<props>
<prop key="setA*">PROPAGATION_REQUIRED</prop>
<prop key="rollbackOnly">PROPAGATION_REQUIRED</prop>
<prop key="echoException">PROPAGATION_REQUIRED,+javax.servlet.ServletException,-java.lang.Exception</prop>
<prop key="echoException">PROPAGATION_REQUIRED,+jakarta.servlet.ServletException,-java.lang.Exception</prop>
</props>
</property>
</bean>
+1
View File
@@ -18,6 +18,7 @@ include "spring-context"
include "spring-context-indexer"
include "spring-context-support"
include "spring-core"
include "spring-core-test"
include "spring-expression"
include "spring-instrument"
include "spring-jcl"
-1
View File
@@ -5,7 +5,6 @@ dependencies {
api(project(":spring-core"))
optional("org.aspectj:aspectjweaver")
optional("org.apache.commons:commons-pool2")
optional("com.jamonapi:jamon")
testImplementation(testFixtures(project(":spring-beans")))
testImplementation(testFixtures(project(":spring-core")))
testFixturesImplementation(testFixtures(project(":spring-beans")))
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -78,10 +78,9 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
*/
public static JoinPoint currentJoinPoint() {
MethodInvocation mi = ExposeInvocationInterceptor.currentInvocation();
if (!(mi instanceof ProxyMethodInvocation)) {
if (!(mi instanceof ProxyMethodInvocation pmi)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
JoinPoint jp = (JoinPoint) pmi.getUserAttribute(JOIN_POINT_KEY);
if (jp == null) {
jp = new MethodInvocationProceedingJoinPoint(pmi);
@@ -262,7 +261,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
public void setArgumentNamesFromStringArray(String... args) {
this.argumentNames = new String[args.length];
for (int i = 0; i < args.length; i++) {
this.argumentNames[i] = StringUtils.trimWhitespace(args[i]);
this.argumentNames[i] = args[i].strip();
if (!isVariableName(this.argumentNames[i])) {
throw new IllegalArgumentException(
"'argumentNames' property of AbstractAspectJAdvice contains an argument name '" +
@@ -714,10 +713,9 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
if (this == other) {
return true;
}
if (!(other instanceof AdviceExcludingMethodMatcher)) {
if (!(other instanceof AdviceExcludingMethodMatcher otherMm)) {
return false;
}
AdviceExcludingMethodMatcher otherMm = (AdviceExcludingMethodMatcher) other;
return this.adviceMethod.equals(otherMm.adviceMethod);
}
@@ -158,7 +158,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
/** The pointcut expression associated with the advice, as a simple String. */
@Nullable
private String pointcutExpression;
private final String pointcutExpression;
private boolean raiseExceptions;
@@ -486,7 +486,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
}
String[] tokens = StringUtils.tokenizeToStringArray(argsSpec, ",");
for (int i = 0; i < tokens.length; i++) {
tokens[i] = StringUtils.trimWhitespace(tokens[i]);
tokens[i] = tokens[i].strip();
String varName = maybeExtractVariableName(tokens[i]);
if (varName != null) {
varNames.add(varName);
@@ -759,10 +759,10 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
*/
private static class PointcutBody {
private int numTokensConsumed;
private final int numTokensConsumed;
@Nullable
private String text;
private final String text;
public PointcutBody(int tokens, @Nullable String text) {
this.numTokensConsumed = tokens;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -63,10 +63,9 @@ public class AspectJAroundAdvice extends AbstractAspectJAdvice implements Method
@Override
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
if (!(mi instanceof ProxyMethodInvocation pmi)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
JoinPointMatch jpm = getJoinPointMatch(pmi);
return invokeAdviceMethod(pjp, jpm, null, null);
@@ -523,10 +523,9 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
if (this == other) {
return true;
}
if (!(other instanceof AspectJExpressionPointcut)) {
if (!(other instanceof AspectJExpressionPointcut otherPc)) {
return false;
}
AspectJExpressionPointcut otherPc = (AspectJExpressionPointcut) other;
return ObjectUtils.nullSafeEquals(this.getExpression(), otherPc.getExpression()) &&
ObjectUtils.nullSafeEquals(this.pointcutDeclarationScope, otherPc.pointcutDeclarationScope) &&
ObjectUtils.nullSafeEquals(this.pointcutParameterNames, otherPc.pointcutParameterNames) &&
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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.
@@ -97,10 +97,9 @@ public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered {
if (this == other) {
return true;
}
if (!(other instanceof AspectJPointcutAdvisor)) {
if (!(other instanceof AspectJPointcutAdvisor otherAdvisor)) {
return false;
}
AspectJPointcutAdvisor otherAdvisor = (AspectJPointcutAdvisor) other;
return this.advice.equals(otherAdvisor.advice);
}
@@ -214,8 +214,7 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
private String resolveExpression(A annotation) {
for (String attributeName : EXPRESSION_ATTRIBUTES) {
Object val = AnnotationUtils.getValue(annotation, attributeName);
if (val instanceof String) {
String str = (String) val;
if (val instanceof String str) {
if (!str.isEmpty()) {
return str;
}
@@ -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.
@@ -101,24 +101,22 @@ public class AspectMetadata implements Serializable {
this.ajType = ajType;
switch (this.ajType.getPerClause().getKind()) {
case SINGLETON:
case SINGLETON -> {
this.perClausePointcut = Pointcut.TRUE;
return;
case PERTARGET:
case PERTHIS:
}
case PERTARGET, PERTHIS -> {
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setLocation(aspectClass.getName());
ajexp.setExpression(findPerClause(aspectClass));
ajexp.setPointcutDeclarationScope(aspectClass);
this.perClausePointcut = ajexp;
return;
case PERTYPEWITHIN:
}
case PERTYPEWITHIN -> {
// Works with a type pattern
this.perClausePointcut = new ComposablePointcut(new TypePatternClassFilter(findPerClause(aspectClass)));
return;
default:
throw new AopConfigException(
"PerClause " + ajType.getPerClause().getKind() + " not supported by Spring AOP for " + aspectClass);
}
default -> throw new AopConfigException(
"PerClause " + ajType.getPerClause().getKind() + " not supported by Spring AOP for " + aspectClass);
}
}
@@ -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.
@@ -220,21 +220,18 @@ final class InstantiationModelAwarePointcutAdvisorImpl
}
else {
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
case AtAround:
case AtPointcut, AtAround -> {
this.isBeforeAdvice = false;
this.isAfterAdvice = false;
break;
case AtBefore:
}
case AtBefore -> {
this.isBeforeAdvice = true;
this.isAfterAdvice = false;
break;
case AtAfter:
case AtAfterReturning:
case AtAfterThrowing:
}
case AtAfter, AtAfterReturning, AtAfterThrowing -> {
this.isBeforeAdvice = false;
this.isAfterAdvice = true;
break;
}
}
}
}
@@ -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.
@@ -261,42 +261,36 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
AbstractAspectJAdvice springAdvice;
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
case AtPointcut -> {
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
}
case AtAround -> springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
case AtBefore -> springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
case AtAfter -> springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
case AtAfterReturning -> {
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
}
case AtAfterThrowing -> {
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
default -> throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
// Now to configure the advice...
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2021 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.
@@ -59,8 +59,7 @@ class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
NodeList childNodes = element.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if (node instanceof Element) {
Element includeElement = (Element) node;
if (node instanceof Element includeElement) {
TypedStringValue valueHolder = new TypedStringValue(includeElement.getAttribute("name"));
valueHolder.setSource(parserContext.extractSource(includeElement));
includePatterns.add(valueHolder);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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.
@@ -93,7 +93,7 @@ class ConfigBeanDefinitionParser implements BeanDefinitionParser {
private static final int POINTCUT_INDEX = 1;
private static final int ASPECT_INSTANCE_FACTORY_INDEX = 2;
private ParseState parseState = new ParseState();
private final ParseState parseState = new ParseState();
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2021 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.
@@ -42,8 +42,7 @@ class ScopedProxyBeanDefinitionDecorator implements BeanDefinitionDecorator {
@Override
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
boolean proxyTargetClass = true;
if (node instanceof Element) {
Element ele = (Element) node;
if (node instanceof Element ele) {
if (ele.hasAttribute(PROXY_TARGET_CLASS)) {
proxyTargetClass = Boolean.parseBoolean(ele.getAttribute(PROXY_TARGET_CLASS));
}
@@ -69,8 +69,7 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyProcessorSu
return bean;
}
if (bean instanceof Advised) {
Advised advised = (Advised) bean;
if (bean instanceof Advised advised) {
if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
// Add our local Advisor to the existing proxy's Advisor chain...
if (this.beforeExistingAdvisors) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -283,8 +283,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
}
Advisor advisor = this.advisors.remove(index);
if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (advisor instanceof IntroductionAdvisor ia) {
// We need to remove introduction interfaces.
for (Class<?> ifc : ia.getInterfaces()) {
removeInterface(ifc);
@@ -33,7 +33,6 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
/**
* Utility methods for AOP proxy factories.
@@ -49,11 +48,6 @@ import org.springframework.util.ReflectionUtils;
*/
public abstract class AopProxyUtils {
// JDK 17 Class.isSealed() method available?
@Nullable
private static final Method isSealedMethod = ClassUtils.getMethodIfAvailable(Class.class, "isSealed");
/**
* Obtain the singleton target object behind the given proxy, if any.
* @param candidate the (potential) proxy to check
@@ -143,7 +137,7 @@ public abstract class AopProxyUtils {
List<Class<?>> proxiedInterfaces = new ArrayList<>(specifiedInterfaces.length + 3);
for (Class<?> ifc : specifiedInterfaces) {
// Only non-sealed interfaces are actually eligible for JDK proxying (on JDK 17)
if (isSealedMethod == null || Boolean.FALSE.equals(ReflectionUtils.invokeMethod(isSealedMethod, ifc))) {
if (!ifc.isSealed()) {
proxiedInterfaces.add(ifc);
}
}
@@ -949,10 +949,9 @@ class CglibAopProxy implements AopProxy, Serializable {
if (this == other) {
return true;
}
if (!(other instanceof ProxyCallbackFilter)) {
if (!(other instanceof ProxyCallbackFilter otherCallbackFilter)) {
return false;
}
ProxyCallbackFilter otherCallbackFilter = (ProxyCallbackFilter) other;
AdvisedSupport otherAdvised = otherCallbackFilter.advised;
if (this.advised.isFrozen() != otherAdvised.isFrozen()) {
return false;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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.
@@ -60,9 +60,8 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
Boolean hasIntroductions = null;
for (Advisor advisor : advisors) {
if (advisor instanceof PointcutAdvisor) {
if (advisor instanceof PointcutAdvisor pointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
@@ -90,8 +89,7 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
else if (advisor instanceof IntroductionAdvisor ia) {
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
@@ -111,8 +109,7 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
*/
private static boolean hasMatchingIntroductions(Advisor[] advisors, Class<?> actualClass) {
for (Advisor advisor : advisors) {
if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (advisor instanceof IntroductionAdvisor ia) {
if (ia.getClassFilter().matches(actualClass)) {
return true;
}
@@ -475,8 +475,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
Advisor[] advisors = getAdvisors();
List<Advisor> freshAdvisors = new ArrayList<>(advisors.length);
for (Advisor advisor : advisors) {
if (advisor instanceof PrototypePlaceholderAdvisor) {
PrototypePlaceholderAdvisor pa = (PrototypePlaceholderAdvisor) advisor;
if (advisor instanceof PrototypePlaceholderAdvisor pa) {
if (logger.isDebugEnabled()) {
logger.debug("Refreshing bean named '" + pa.getBeanName() + "'");
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -165,11 +165,9 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher dm) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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.
@@ -58,10 +58,9 @@ public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Se
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
if (!(adviceObject instanceof Advice)) {
if (!(adviceObject instanceof Advice advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
@@ -25,7 +25,6 @@ import org.springframework.beans.factory.FactoryBean;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.PatternMatchUtils;
import org.springframework.util.StringUtils;
/**
* Auto proxy creator that identifies beans to proxy via a list of names.
@@ -69,7 +68,7 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
Assert.notEmpty(beanNames, "'beanNames' must not be empty");
this.beanNames = new ArrayList<>(beanNames.length);
for (String mappedName : beanNames) {
this.beanNames.add(StringUtils.trimWhitespace(mappedName));
this.beanNames.add(mappedName.strip());
}
}
@@ -34,6 +34,8 @@ import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.EmbeddedValueResolver;
import org.springframework.core.task.AsyncListenableTaskExecutor;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;
@@ -156,7 +158,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
/**
* Determine the specific executor to use when executing the given method.
* Should preferably return an {@link AsyncListenableTaskExecutor} implementation.
* <p>Should preferably return an {@link AsyncListenableTaskExecutor} implementation.
* @return the executor to use (or {@code null}, but just if no default executor is available)
*/
@Nullable
@@ -184,7 +186,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
/**
* Return the qualifier or bean name of the executor to be used when executing the
* given async method, typically specified in the form of an annotation attribute.
* Returning an empty string or {@code null} indicates that no specific executor has
* <p>Returning an empty string or {@code null} indicates that no specific executor has
* been specified and that the {@linkplain #setExecutor(Executor) default executor}
* should be used.
* @param method the method to inspect for executor qualifier metadata
@@ -208,12 +210,16 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
throw new IllegalStateException("BeanFactory must be set on " + getClass().getSimpleName() +
" to access qualified executor '" + qualifier + "'");
}
if (beanFactory instanceof ConfigurableBeanFactory configurableBeanFactory) {
EmbeddedValueResolver embeddedValueResolver = new EmbeddedValueResolver(configurableBeanFactory);
qualifier = embeddedValueResolver.resolveStringValue(qualifier);
}
return BeanFactoryAnnotationUtils.qualifiedBeanOfType(beanFactory, Executor.class, qualifier);
}
/**
* Retrieve or build a default executor for this advice instance.
* An executor returned from here will be cached for further use.
* <p>An executor returned from here will be cached for further use.
* <p>The default implementation searches for a unique {@link TaskExecutor} bean
* in the context, or for an {@link Executor} bean named "taskExecutor" otherwise.
* If neither of the two is resolvable, this implementation will return {@code null}.
@@ -288,10 +294,14 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
else if (Future.class.isAssignableFrom(returnType)) {
return executor.submit(task);
}
else {
else if (void.class == returnType) {
executor.submit(task);
return null;
}
else {
throw new IllegalArgumentException(
"Invalid return type for async method (only Future and void supported): " + returnType);
}
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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.
@@ -47,7 +47,7 @@ import org.springframework.util.ClassUtils;
* target method needs to implement the same signature, it will have to return
* a temporary Future handle that just passes the return value through
* (like Spring's {@link org.springframework.scheduling.annotation.AsyncResult}
* or EJB 3.1's {@code javax.ejb.AsyncResult}).
* or EJB's {@code jakarta.ejb.AsyncResult}).
*
* <p>When the return type is {@code java.util.concurrent.Future}, any exception thrown
* during the execution can be accessed and managed by the caller. With {@code void}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -299,7 +299,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
Object target = methodInvocation.getThis();
Assert.state(target != null, "Target must not be null");
StringBuffer output = new StringBuffer();
StringBuilder output = new StringBuilder();
while (matcher.find()) {
String match = matcher.group();
if (PLACEHOLDER_METHOD_NAME.equals(match)) {
@@ -341,15 +341,15 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
/**
* Adds the {@code String} representation of the method return value
* to the supplied {@code StringBuffer}. Correctly handles
* to the supplied {@code StringBuilder}. Correctly handles
* {@code null} and {@code void} results.
* @param methodInvocation the {@code MethodInvocation} that returned the value
* @param matcher the {@code Matcher} containing the matched placeholder
* @param output the {@code StringBuffer} to write output to
* @param output the {@code StringBuilder} to write output to
* @param returnValue the value returned by the method invocation.
*/
private void appendReturnValue(
MethodInvocation methodInvocation, Matcher matcher, StringBuffer output, @Nullable Object returnValue) {
MethodInvocation methodInvocation, Matcher matcher, StringBuilder output, @Nullable Object returnValue) {
if (methodInvocation.getMethod().getReturnType() == void.class) {
matcher.appendReplacement(output, "void");
@@ -370,9 +370,9 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
* @param methodInvocation the {@code MethodInvocation} being logged.
* Arguments will be retrieved from the corresponding {@code Method}.
* @param matcher the {@code Matcher} containing the state of the output
* @param output the {@code StringBuffer} containing the output
* @param output the {@code StringBuilder} containing the output
*/
private void appendArgumentTypes(MethodInvocation methodInvocation, Matcher matcher, StringBuffer output) {
private void appendArgumentTypes(MethodInvocation methodInvocation, Matcher matcher, StringBuilder output) {
Class<?>[] argumentTypes = methodInvocation.getMethod().getParameterTypes();
String[] argumentTypeShortNames = new String[argumentTypes.length];
for (int i = 0; i < argumentTypeShortNames.length; i++) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -68,10 +68,9 @@ public abstract class ExposeBeanNameAdvisors {
* @throws IllegalStateException if the bean name has not been exposed
*/
public static String getBeanName(MethodInvocation mi) throws IllegalStateException {
if (!(mi instanceof ProxyMethodInvocation)) {
if (!(mi instanceof ProxyMethodInvocation pmi)) {
throw new IllegalArgumentException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
String beanName = (String) pmi.getUserAttribute(BEAN_NAME_ATTRIBUTE);
if (beanName == null) {
throw new IllegalStateException("Cannot get bean name; not set on MethodInvocation: " + mi);
@@ -113,10 +112,9 @@ public abstract class ExposeBeanNameAdvisors {
@Override
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
if (!(mi instanceof ProxyMethodInvocation pmi)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
pmi.setUserAttribute(BEAN_NAME_ATTRIBUTE, this.beanName);
return mi.proceed();
}
@@ -138,10 +136,9 @@ public abstract class ExposeBeanNameAdvisors {
@Override
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
if (!(mi instanceof ProxyMethodInvocation pmi)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
pmi.setUserAttribute(BEAN_NAME_ATTRIBUTE, this.beanName);
return super.invoke(mi);
}
@@ -1,144 +0,0 @@
/*
* Copyright 2002-2017 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.interceptor;
import com.jamonapi.MonKey;
import com.jamonapi.MonKeyImp;
import com.jamonapi.Monitor;
import com.jamonapi.MonitorFactory;
import com.jamonapi.utils.Misc;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
/**
* Performance monitor interceptor that uses <b>JAMon</b> library to perform the
* performance measurement on the intercepted method and output the stats.
* In addition, it tracks/counts exceptions thrown by the intercepted method.
* The stack traces can be viewed in the JAMon web application.
*
* <p>This code is inspired by Thierry Templier's blog.
*
* @author Dmitriy Kopylenko
* @author Juergen Hoeller
* @author Rob Harrop
* @author Steve Souza
* @since 1.1.3
* @see com.jamonapi.MonitorFactory
* @see PerformanceMonitorInterceptor
*/
@SuppressWarnings("serial")
public class JamonPerformanceMonitorInterceptor extends AbstractMonitoringInterceptor {
private boolean trackAllInvocations = false;
/**
* Create a new JamonPerformanceMonitorInterceptor with a static logger.
*/
public JamonPerformanceMonitorInterceptor() {
}
/**
* Create a new JamonPerformanceMonitorInterceptor with a dynamic or static logger,
* according to the given flag.
* @param useDynamicLogger whether to use a dynamic logger or a static logger
* @see #setUseDynamicLogger
*/
public JamonPerformanceMonitorInterceptor(boolean useDynamicLogger) {
setUseDynamicLogger(useDynamicLogger);
}
/**
* Create a new JamonPerformanceMonitorInterceptor with a dynamic or static logger,
* according to the given flag.
* @param useDynamicLogger whether to use a dynamic logger or a static logger
* @param trackAllInvocations whether to track all invocations that go through
* this interceptor, or just invocations with trace logging enabled
* @see #setUseDynamicLogger
*/
public JamonPerformanceMonitorInterceptor(boolean useDynamicLogger, boolean trackAllInvocations) {
setUseDynamicLogger(useDynamicLogger);
setTrackAllInvocations(trackAllInvocations);
}
/**
* Set whether to track all invocations that go through this interceptor,
* or just invocations with trace logging enabled.
* <p>Default is "false": Only invocations with trace logging enabled will
* be monitored. Specify "true" to let JAMon track all invocations,
* gathering statistics even when trace logging is disabled.
*/
public void setTrackAllInvocations(boolean trackAllInvocations) {
this.trackAllInvocations = trackAllInvocations;
}
/**
* Always applies the interceptor if the "trackAllInvocations" flag has been set;
* else just kicks in if the log is enabled.
* @see #setTrackAllInvocations
* @see #isLogEnabled
*/
@Override
protected boolean isInterceptorEnabled(MethodInvocation invocation, Log logger) {
return (this.trackAllInvocations || isLogEnabled(logger));
}
/**
* Wraps the invocation with a JAMon Monitor and writes the current
* performance statistics to the log (if enabled).
* @see com.jamonapi.MonitorFactory#start
* @see com.jamonapi.Monitor#stop
*/
@Override
protected Object invokeUnderTrace(MethodInvocation invocation, Log logger) throws Throwable {
String name = createInvocationTraceName(invocation);
MonKey key = new MonKeyImp(name, name, "ms.");
Monitor monitor = MonitorFactory.start(key);
try {
return invocation.proceed();
}
catch (Throwable ex) {
trackException(key, ex);
throw ex;
}
finally {
monitor.stop();
if (!this.trackAllInvocations || isLogEnabled(logger)) {
writeToLog(logger, "JAMon performance statistics for method [" + name + "]:\n" + monitor);
}
}
}
/**
* Count the thrown exception and put the stack trace in the details portion of the key.
* This will allow the stack trace to be viewed in the JAMon web application.
*/
protected void trackException(MonKey key, Throwable ex) {
String stackTrace = "stackTrace=" + Misc.getExceptionTrace(ex);
key.setDetails(stackTrace);
// Specific exception counter. Example: java.lang.RuntimeException
MonitorFactory.add(new MonKeyImp(ex.getClass().getName(), stackTrace, "Exception"), 1);
// General exception counter which is a total for all exceptions thrown
MonitorFactory.add(new MonKeyImp(MonitorFactory.EXCEPTIONS_LABEL, stackTrace, "Exception"), 1);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2021 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.
@@ -31,7 +31,6 @@ import org.springframework.util.StopWatch;
* @author Dmitriy Kopylenko
* @author Rob Harrop
* @see org.springframework.util.StopWatch
* @see JamonPerformanceMonitorInterceptor
*/
@SuppressWarnings("serial")
public class PerformanceMonitorInterceptor extends AbstractMonitoringInterceptor {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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.
@@ -85,11 +85,9 @@ public class ScopedProxyFactoryBean extends ProxyConfig
@Override
public void setBeanFactory(BeanFactory beanFactory) {
if (!(beanFactory instanceof ConfigurableBeanFactory)) {
if (!(beanFactory instanceof ConfigurableBeanFactory cbf)) {
throw new IllegalStateException("Not running in a ConfigurableBeanFactory: " + beanFactory);
}
ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) beanFactory;
this.scopedTargetSource.setBeanFactory(beanFactory);
ProxyFactory pf = new ProxyFactory();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2021 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.
@@ -69,10 +69,9 @@ public abstract class AbstractPointcutAdvisor implements PointcutAdvisor, Ordere
if (this == other) {
return true;
}
if (!(other instanceof PointcutAdvisor)) {
if (!(other instanceof PointcutAdvisor otherAdvisor)) {
return false;
}
PointcutAdvisor otherAdvisor = (PointcutAdvisor) other;
return (ObjectUtils.nullSafeEquals(getAdvice(), otherAdvisor.getAdvice()) &&
ObjectUtils.nullSafeEquals(getPointcut(), otherAdvisor.getPointcut()));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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.
@@ -24,7 +24,6 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* Abstract base regular expression pointcut bean. JavaBean properties are:
@@ -81,7 +80,7 @@ public abstract class AbstractRegexpMethodPointcut extends StaticMethodMatcherPo
Assert.notEmpty(patterns, "'patterns' must not be empty");
this.patterns = new String[patterns.length];
for (int i = 0; i < patterns.length; i++) {
this.patterns[i] = StringUtils.trimWhitespace(patterns[i]);
this.patterns[i] = patterns[i].strip();
}
initPatternRepresentation(this.patterns);
}
@@ -111,7 +110,7 @@ public abstract class AbstractRegexpMethodPointcut extends StaticMethodMatcherPo
Assert.notEmpty(excludedPatterns, "'excludedPatterns' must not be empty");
this.excludedPatterns = new String[excludedPatterns.length];
for (int i = 0; i < excludedPatterns.length; i++) {
this.excludedPatterns[i] = StringUtils.trimWhitespace(excludedPatterns[i]);
this.excludedPatterns[i] = excludedPatterns[i].strip();
}
initExcludedPatternRepresentation(this.excludedPatterns);
}
@@ -200,10 +199,9 @@ public abstract class AbstractRegexpMethodPointcut extends StaticMethodMatcherPo
if (this == other) {
return true;
}
if (!(other instanceof AbstractRegexpMethodPointcut)) {
if (!(other instanceof AbstractRegexpMethodPointcut otherPointcut)) {
return false;
}
AbstractRegexpMethodPointcut otherPointcut = (AbstractRegexpMethodPointcut) other;
return (Arrays.equals(this.patterns, otherPointcut.patterns) &&
Arrays.equals(this.excludedPatterns, otherPointcut.excludedPatterns));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -284,8 +284,7 @@ public abstract class AopUtils {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
else if (advisor instanceof PointcutAdvisor pca) {
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -188,10 +188,9 @@ public class ComposablePointcut implements Pointcut, Serializable {
if (this == other) {
return true;
}
if (!(other instanceof ComposablePointcut)) {
if (!(other instanceof ComposablePointcut otherPointcut)) {
return false;
}
ComposablePointcut otherPointcut = (ComposablePointcut) other;
return (this.classFilter.equals(otherPointcut.classFilter) &&
this.methodMatcher.equals(otherPointcut.methodMatcher));
}
@@ -128,10 +128,9 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
if (this == other) {
return true;
}
if (!(other instanceof ControlFlowPointcut)) {
if (!(other instanceof ControlFlowPointcut that)) {
return false;
}
ControlFlowPointcut that = (ControlFlowPointcut) other;
return (this.clazz.equals(that.clazz)) && ObjectUtils.nullSafeEquals(this.methodName, that.methodName);
}
@@ -155,10 +155,9 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
if (this == other) {
return true;
}
if (!(other instanceof DefaultIntroductionAdvisor)) {
if (!(other instanceof DefaultIntroductionAdvisor otherAdvisor)) {
return false;
}
DefaultIntroductionAdvisor otherAdvisor = (DefaultIntroductionAdvisor) other;
return (this.advice.equals(otherAdvisor.advice) && this.interfaces.equals(otherAdvisor.interfaces));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2021 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.
@@ -61,9 +61,9 @@ public class DelegatePerTargetObjectIntroductionInterceptor extends Introduction
*/
private final Map<Object, Object> delegateMap = new WeakHashMap<>();
private Class<?> defaultImplType;
private final Class<?> defaultImplType;
private Class<?> interfaceType;
private final Class<?> interfaceType;
public DelegatePerTargetObjectIntroductionInterceptor(Class<?> defaultImplType, Class<?> interfaceType) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -146,10 +146,9 @@ public abstract class MethodMatchers {
if (this == other) {
return true;
}
if (!(other instanceof UnionMethodMatcher)) {
if (!(other instanceof UnionMethodMatcher that)) {
return false;
}
UnionMethodMatcher that = (UnionMethodMatcher) other;
return (this.mm1.equals(that.mm1) && this.mm2.equals(that.mm2));
}
@@ -223,8 +222,7 @@ public abstract class MethodMatchers {
}
ClassFilter otherCf1 = ClassFilter.TRUE;
ClassFilter otherCf2 = ClassFilter.TRUE;
if (other instanceof ClassFilterAwareUnionMethodMatcher) {
ClassFilterAwareUnionMethodMatcher cfa = (ClassFilterAwareUnionMethodMatcher) other;
if (other instanceof ClassFilterAwareUnionMethodMatcher cfa) {
otherCf1 = cfa.cf1;
otherCf2 = cfa.cf2;
}
@@ -312,10 +310,9 @@ public abstract class MethodMatchers {
if (this == other) {
return true;
}
if (!(other instanceof IntersectionMethodMatcher)) {
if (!(other instanceof IntersectionMethodMatcher that)) {
return false;
}
IntersectionMethodMatcher that = (IntersectionMethodMatcher) other;
return (this.mm1.equals(that.mm1) && this.mm2.equals(that.mm2));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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.
@@ -72,10 +72,9 @@ public class AnnotationClassFilter implements ClassFilter {
if (this == other) {
return true;
}
if (!(other instanceof AnnotationClassFilter)) {
if (!(other instanceof AnnotationClassFilter otherCf)) {
return false;
}
AnnotationClassFilter otherCf = (AnnotationClassFilter) other;
return (this.annotationType.equals(otherCf.annotationType) && this.checkInherited == otherCf.checkInherited);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -125,10 +125,9 @@ public class AnnotationMatchingPointcut implements Pointcut {
if (this == other) {
return true;
}
if (!(other instanceof AnnotationMatchingPointcut)) {
if (!(other instanceof AnnotationMatchingPointcut otherPointcut)) {
return false;
}
AnnotationMatchingPointcut otherPointcut = (AnnotationMatchingPointcut) other;
return (this.classFilter.equals(otherPointcut.classFilter) &&
this.methodMatcher.equals(otherPointcut.methodMatcher));
}
@@ -189,10 +188,9 @@ public class AnnotationMatchingPointcut implements Pointcut {
if (this == obj) {
return true;
}
if (!(obj instanceof AnnotationCandidateClassFilter)) {
if (!(obj instanceof AnnotationCandidateClassFilter that)) {
return false;
}
AnnotationCandidateClassFilter that = (AnnotationCandidateClassFilter) obj;
return this.annotationType.equals(that.annotationType);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -92,10 +92,9 @@ public class AnnotationMethodMatcher extends StaticMethodMatcher {
if (this == other) {
return true;
}
if (!(other instanceof AnnotationMethodMatcher)) {
if (!(other instanceof AnnotationMethodMatcher otherMm)) {
return false;
}
AnnotationMethodMatcher otherMm = (AnnotationMethodMatcher) other;
return (this.annotationType.equals(otherMm.annotationType) && this.checkInherited == otherMm.checkInherited);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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.
@@ -135,10 +135,9 @@ public final class EmptyTargetSource implements TargetSource, Serializable {
if (this == other) {
return true;
}
if (!(other instanceof EmptyTargetSource)) {
if (!(other instanceof EmptyTargetSource otherTs)) {
return false;
}
EmptyTargetSource otherTs = (EmptyTargetSource) other;
return (ObjectUtils.nullSafeEquals(this.targetClass, otherTs.targetClass) && this.isStatic == otherTs.isStatic);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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.
@@ -85,10 +85,9 @@ public class SingletonTargetSource implements TargetSource, Serializable {
if (this == other) {
return true;
}
if (!(other instanceof SingletonTargetSource)) {
if (!(other instanceof SingletonTargetSource otherTargetSource)) {
return false;
}
SingletonTargetSource otherTargetSource = (SingletonTargetSource) other;
return this.target.equals(otherTargetSource.target);
}
@@ -1,79 +0,0 @@
/*
* Copyright 2002-2019 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.interceptor;
import com.jamonapi.MonitorFactory;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* @author Steve Souza
* @since 4.1
*/
public class JamonPerformanceMonitorInterceptorTests {
private final JamonPerformanceMonitorInterceptor interceptor = new JamonPerformanceMonitorInterceptor();
private final MethodInvocation mi = mock(MethodInvocation.class);
private final Log log = mock(Log.class);
@BeforeEach
public void setUp() {
MonitorFactory.reset();
}
@AfterEach
public void tearDown() {
MonitorFactory.reset();
}
@Test
public void testInvokeUnderTraceWithNormalProcessing() throws Throwable {
given(mi.getMethod()).willReturn(String.class.getMethod("toString"));
interceptor.invokeUnderTrace(mi, log);
assertThat(MonitorFactory.getNumRows() > 0).as("jamon must track the method being invoked").isTrue();
assertThat(MonitorFactory.getReport().contains("toString")).as("The jamon report must contain the toString method that was invoked").isTrue();
}
@Test
public void testInvokeUnderTraceWithExceptionTracking() throws Throwable {
given(mi.getMethod()).willReturn(String.class.getMethod("toString"));
given(mi.proceed()).willThrow(new IllegalArgumentException());
assertThatIllegalArgumentException().isThrownBy(() ->
interceptor.invokeUnderTrace(mi, log));
assertThat(MonitorFactory.getNumRows()).as("Monitors must exist for the method invocation and 2 exceptions").isEqualTo(3);
assertThat(MonitorFactory.getReport().contains("toString")).as("The jamon report must contain the toString method that was invoked").isTrue();
assertThat(MonitorFactory.getReport().contains(MonitorFactory.EXCEPTIONS_LABEL)).as("The jamon report must contain the generic exception: " + MonitorFactory.EXCEPTIONS_LABEL).isTrue();
assertThat(MonitorFactory.getReport().contains("IllegalArgumentException")).as("The jamon report must contain the specific exception: IllegalArgumentException'").isTrue();
}
}
+10 -3
View File
@@ -8,7 +8,14 @@ sourceSets.main.java.srcDirs = files()
sourceSets.test.aspectj.srcDir "src/test/java"
sourceSets.test.java.srcDirs = files()
aspectj.version = dependencyManagement.managedVersions['org.aspectj:aspectjweaver']
compileAspectj {
sourceCompatibility "17"
targetCompatibility "17"
}
compileTestAspectj {
sourceCompatibility "17"
targetCompatibility "17"
}
dependencies {
api("org.aspectj:aspectjweaver")
@@ -20,14 +27,14 @@ dependencies {
optional(project(":spring-orm")) // for JPA exception translation support
optional(project(":spring-tx")) // for JPA, @Transactional support
optional("javax.cache:cache-api") // for JCache aspect
optional("javax.transaction:javax.transaction-api") // for @javax.transaction.Transactional support
optional("jakarta.transaction:jakarta.transaction-api") // for @jakarta.transaction.Transactional support
testImplementation(project(":spring-core")) // for CodeStyleAspect
testImplementation(project(":spring-test"))
testImplementation(testFixtures(project(":spring-context")))
testImplementation(testFixtures(project(":spring-context-support")))
testImplementation(testFixtures(project(":spring-core")))
testImplementation(testFixtures(project(":spring-tx")))
testImplementation("javax.mail:javax.mail-api")
testImplementation("jakarta.mail:jakarta.mail-api")
testCompileOnly("org.aspectj:aspectjrt")
}
@@ -27,7 +27,7 @@ import org.springframework.transaction.config.TransactionManagementConfigUtils;
/**
* {@code @Configuration} class that registers the Spring infrastructure beans necessary
* to enable AspectJ-based annotation-driven transaction management for the JTA 1.2
* {@link javax.transaction.Transactional} annotation in addition to Spring's own
* {@link jakarta.transaction.Transactional} annotation in addition to Spring's own
* {@link org.springframework.transaction.annotation.Transactional} annotation.
*
* @author Juergen Hoeller
@@ -16,7 +16,7 @@
package org.springframework.transaction.aspectj;
import javax.transaction.Transactional;
import jakarta.transaction.Transactional;
import org.aspectj.lang.annotation.RequiredTypes;
@@ -24,7 +24,7 @@ import org.springframework.transaction.annotation.AnnotationTransactionAttribute
/**
* Concrete AspectJ transaction aspect using the JTA 1.2
* {@link javax.transaction.Transactional} annotation.
* {@link jakarta.transaction.Transactional} annotation.
*
* <p>When using this aspect, you <i>must</i> annotate the implementation class
* (and/or methods within that class), <i>not</i> the interface (if any) that
@@ -42,10 +42,10 @@ import org.springframework.transaction.annotation.AnnotationTransactionAttribute
*
* @author Stephane Nicoll
* @since 4.2
* @see javax.transaction.Transactional
* @see jakarta.transaction.Transactional
* @see AnnotationTransactionAspect
*/
@RequiredTypes("javax.transaction.Transactional")
@RequiredTypes("jakarta.transaction.Transactional")
public aspect JtaAnnotationTransactionAspect extends AbstractTransactionAspect {
public JtaAnnotationTransactionAspect() {
@@ -21,7 +21,7 @@ import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.CachingConfigurer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.CacheResolver;
@@ -143,7 +143,7 @@ public class AspectJEnableCachingIsolatedTests {
@Configuration
@EnableCaching(mode = AdviceMode.ASPECTJ)
static class EnableCachingConfig extends CachingConfigurerSupport {
static class EnableCachingConfig implements CachingConfigurer {
@Override
@Bean
@@ -220,7 +220,7 @@ public class AspectJEnableCachingIsolatedTests {
@Configuration
@EnableCaching(mode = AdviceMode.ASPECTJ)
static class MultiCacheManagerConfigurer extends CachingConfigurerSupport {
static class MultiCacheManagerConfigurer implements CachingConfigurer {
@Bean
public CacheManager cm1() {
@@ -246,7 +246,7 @@ public class AspectJEnableCachingIsolatedTests {
@Configuration
@EnableCaching(mode = AdviceMode.ASPECTJ)
static class EmptyConfigSupportConfig extends CachingConfigurerSupport {
static class EmptyConfigSupportConfig implements CachingConfigurer {
@Bean
public CacheManager cm() {
@@ -258,7 +258,7 @@ public class AspectJEnableCachingIsolatedTests {
@Configuration
@EnableCaching(mode = AdviceMode.ASPECTJ)
static class FullCachingConfig extends CachingConfigurerSupport {
static class FullCachingConfig implements CachingConfigurer {
@Override
@Bean
@@ -17,7 +17,7 @@
package org.springframework.cache.aspectj;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.CachingConfigurer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.config.AnnotatedClassCacheableService;
import org.springframework.cache.config.CacheableService;
@@ -47,7 +47,7 @@ public class AspectJEnableCachingTests extends AbstractCacheAnnotationTests {
@Configuration
@EnableCaching(mode = AdviceMode.ASPECTJ)
static class EnableCachingConfig extends CachingConfigurerSupport {
static class EnableCachingConfig implements CachingConfigurer {
@Override
@Bean
@@ -18,8 +18,7 @@ package org.springframework.transaction.aspectj;
import java.io.IOException;
import javax.transaction.Transactional;
import jakarta.transaction.Transactional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+5 -26
View File
@@ -1,38 +1,17 @@
description = "Spring Beans"
apply plugin: "groovy"
apply plugin: "kotlin"
dependencies {
api(project(":spring-core"))
optional("javax.inject:javax.inject")
optional("jakarta.inject:jakarta.inject-api")
optional("org.yaml:snakeyaml")
optional("org.codehaus.groovy:groovy-xml")
optional("org.apache.groovy:groovy-xml")
optional("org.jetbrains.kotlin:kotlin-reflect")
optional("org.jetbrains.kotlin:kotlin-stdlib")
testImplementation(testFixtures(project(":spring-core")))
testImplementation("javax.annotation:javax.annotation-api")
testImplementation(project(":spring-core-test"))
testImplementation("jakarta.annotation:jakarta.annotation-api")
testFixturesApi("org.junit.jupiter:junit-jupiter-api")
testFixturesImplementation("org.assertj:assertj-core")
}
// This module does joint compilation for Java and Groovy code with the compileGroovy task.
sourceSets {
main.groovy.srcDirs += "src/main/java"
main.java.srcDirs = []
}
compileGroovy {
options.compilerArgs += "-Werror"
}
// This module also builds Kotlin code and the compileKotlin task naturally depends on
// compileJava. We need to redefine dependencies to break task cycles.
tasks.named('compileGroovy') {
// Groovy only needs the declared dependencies (and not the result of Java compilation)
classpath = sourceSets.main.compileClasspath
}
tasks.named('compileKotlin') {
// Kotlin also depends on the result of Groovy compilation
classpath += files(sourceSets.main.groovy.classesDirectory)
}
}
@@ -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.
@@ -61,20 +61,15 @@ public class AbstractPropertyAccessorBenchmark {
this.propertyAccessor = new BeanWrapperImpl(this.target);
}
switch (this.customEditor) {
case "stringTrimmer":
case "stringTrimmer" ->
this.propertyAccessor.registerCustomEditor(String.class, new StringTrimmerEditor(false));
break;
case "numberOnPath":
case "numberOnPath" ->
this.propertyAccessor.registerCustomEditor(int.class, "array.somePath", new CustomNumberEditor(Integer.class, false));
break;
case "numberOnNestedPath":
case "numberOnNestedPath" ->
this.propertyAccessor.registerCustomEditor(int.class, "array[0].somePath", new CustomNumberEditor(Integer.class, false));
break;
case "numberOnType":
case "numberOnType" ->
this.propertyAccessor.registerCustomEditor(int.class, new CustomNumberEditor(Integer.class, false));
break;
}
}
}
@@ -98,4 +93,5 @@ public class AbstractPropertyAccessorBenchmark {
this.array = array;
}
}
}
@@ -1,125 +0,0 @@
/*
* Copyright 2002-2013 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.groovy
import groovy.xml.StreamingMarkupBuilder
import org.springframework.beans.factory.config.BeanDefinitionHolder
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate
import org.w3c.dom.Element
/**
* Used by GroovyBeanDefinitionReader to read a Spring XML namespace expression
* in the Groovy DSL.
*
* @author Jeff Brown
* @author Juergen Hoeller
* @since 4.0
*/
@groovy.transform.PackageScope
class GroovyDynamicElementReader extends GroovyObjectSupport {
private final String rootNamespace
private final Map<String, String> xmlNamespaces
private final BeanDefinitionParserDelegate delegate
private final GroovyBeanDefinitionWrapper beanDefinition
protected final boolean decorating;
private boolean callAfterInvocation = true
public GroovyDynamicElementReader(String namespace, Map<String, String> namespaceMap,
BeanDefinitionParserDelegate delegate, GroovyBeanDefinitionWrapper beanDefinition, boolean decorating) {
super();
this.rootNamespace = namespace
this.xmlNamespaces = namespaceMap
this.delegate = delegate
this.beanDefinition = beanDefinition;
this.decorating = decorating;
}
@Override
public Object invokeMethod(String name, Object args) {
if (name.equals("doCall")) {
def callable = args[0]
callable.resolveStrategy = Closure.DELEGATE_FIRST
callable.delegate = this
def result = callable.call()
if (this.callAfterInvocation) {
afterInvocation()
this.callAfterInvocation = false
}
return result
}
else {
StreamingMarkupBuilder builder = new StreamingMarkupBuilder();
def myNamespace = this.rootNamespace
def myNamespaces = this.xmlNamespaces
def callable = {
for (namespace in myNamespaces) {
mkp.declareNamespace([(namespace.key):namespace.value])
}
if (args && (args[-1] instanceof Closure)) {
args[-1].resolveStrategy = Closure.DELEGATE_FIRST
args[-1].delegate = builder
}
delegate."$myNamespace"."$name"(*args)
}
callable.resolveStrategy = Closure.DELEGATE_FIRST
callable.delegate = builder
def writable = builder.bind(callable)
def sw = new StringWriter()
writable.writeTo(sw)
Element element = this.delegate.readerContext.readDocumentFromString(sw.toString()).documentElement
this.delegate.initDefaults(element)
if (this.decorating) {
BeanDefinitionHolder holder = this.beanDefinition.beanDefinitionHolder;
holder = this.delegate.decorateIfRequired(element, holder, null)
this.beanDefinition.setBeanDefinitionHolder(holder)
}
else {
def beanDefinition = this.delegate.parseCustomElement(element)
if (beanDefinition) {
this.beanDefinition.setBeanDefinition(beanDefinition)
}
}
if (this.callAfterInvocation) {
afterInvocation()
this.callAfterInvocation = false
}
return element
}
}
/**
* Hook that subclass or anonymous classes can overwrite to implement custom behavior
* after invocation completes.
*/
protected void afterInvocation() {
// NOOP
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2021 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.
@@ -85,10 +85,9 @@ public class BeanMetadataAttribute implements BeanMetadataElement {
if (this == other) {
return true;
}
if (!(other instanceof BeanMetadataAttribute)) {
if (!(other instanceof BeanMetadataAttribute otherMa)) {
return false;
}
BeanMetadataAttribute otherMa = (BeanMetadataAttribute) other;
return (this.name.equals(otherMa.name) &&
ObjectUtils.nullSafeEquals(this.value, otherMa.value) &&
ObjectUtils.nullSafeEquals(this.source, otherMa.source));
@@ -29,7 +29,6 @@ import java.time.temporal.Temporal;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -79,20 +78,15 @@ public abstract class BeanUtils {
private static final Set<Class<?>> unknownEditorTypes =
Collections.newSetFromMap(new ConcurrentReferenceHashMap<>(64));
private static final Map<Class<?>, Object> DEFAULT_TYPE_VALUES;
static {
Map<Class<?>, Object> values = new HashMap<>();
values.put(boolean.class, false);
values.put(byte.class, (byte) 0);
values.put(short.class, (short) 0);
values.put(int.class, 0);
values.put(long.class, 0L);
values.put(float.class, 0F);
values.put(double.class, 0D);
values.put(char.class, '\0');
DEFAULT_TYPE_VALUES = Collections.unmodifiableMap(values);
}
private static final Map<Class<?>, Object> DEFAULT_TYPE_VALUES = Map.of(
boolean.class, false,
byte.class, (byte) 0,
short.class, (short) 0,
int.class, 0,
long.class, 0L,
float.class, 0F,
double.class, 0D,
char.class, '\0');
/**
@@ -142,19 +136,20 @@ public abstract class BeanUtils {
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
Constructor<T> ctor;
try {
return instantiateClass(clazz.getDeclaredConstructor());
ctor = clazz.getDeclaredConstructor();
}
catch (NoSuchMethodException ex) {
Constructor<T> ctor = findPrimaryConstructor(clazz);
if (ctor != null) {
return instantiateClass(ctor);
ctor = findPrimaryConstructor(clazz);
if (ctor == null) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
catch (LinkageError err) {
throw new BeanInstantiationException(clazz, "Unresolvable class definition", err);
}
return instantiateClass(ctor);
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -18,11 +18,6 @@ package org.springframework.beans;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import org.springframework.core.ResolvableType;
import org.springframework.core.convert.Property;
@@ -69,12 +64,6 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
@Nullable
private CachedIntrospectionResults cachedIntrospectionResults;
/**
* The security context used for invoking the property methods.
*/
@Nullable
private AccessControlContext acc;
/**
* Create a new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards.
@@ -131,7 +120,6 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
*/
private BeanWrapperImpl(Object object, String nestedPath, BeanWrapperImpl parent) {
super(object, nestedPath, parent);
setSecurityContext(parent.acc);
}
@@ -176,23 +164,6 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
return this.cachedIntrospectionResults;
}
/**
* Set the security context used during the invocation of the wrapped instance methods.
* Can be null.
*/
public void setSecurityContext(@Nullable AccessControlContext acc) {
this.acc = acc;
}
/**
* Return the security context used during the invocation of the wrapped instance methods.
* Can be null.
*/
@Nullable
public AccessControlContext getSecurityContext() {
return this.acc;
}
/**
* Convert the given value for the specified property to the latter's type.
@@ -290,23 +261,8 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
@Nullable
public Object getValue() throws Exception {
Method readMethod = this.pd.getReadMethod();
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(readMethod);
return null;
});
try {
return AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
() -> readMethod.invoke(getWrappedInstance(), (Object[]) null), acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
ReflectionUtils.makeAccessible(readMethod);
return readMethod.invoke(getWrappedInstance(), (Object[]) null);
}
ReflectionUtils.makeAccessible(readMethod);
return readMethod.invoke(getWrappedInstance(), (Object[]) null);
}
@Override
@@ -314,23 +270,8 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
this.pd.getWriteMethod());
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(writeMethod);
return null;
});
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
() -> writeMethod.invoke(getWrappedInstance(), value), acc);
}
catch (PrivilegedActionException ex) {
throw ex.getException();
}
}
else {
ReflectionUtils.makeAccessible(writeMethod);
writeMethod.invoke(getWrappedInstance(), value);
}
ReflectionUtils.makeAccessible(writeMethod);
writeMethod.invoke(getWrappedInstance(), value);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -139,7 +139,7 @@ class ExtendedBeanInfo implements BeanInfo {
// Sort non-void returning write methods to guard against the ill effects of
// non-deterministic sorting of methods returned from Class#getDeclaredMethods
// under JDK 7. See https://bugs.java.com/view_bug.do?bug_id=7023180
matches.sort((m1, m2) -> m2.toString().compareTo(m1.toString()));
matches.sort(Comparator.comparing(Method::toString).reversed());
return matches;
}
@@ -188,8 +188,7 @@ class ExtendedBeanInfo implements BeanInfo {
for (PropertyDescriptor pd : this.propertyDescriptors) {
final Class<?> candidateType;
final String candidateName = pd.getName();
if (pd instanceof IndexedPropertyDescriptor) {
IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
if (pd instanceof IndexedPropertyDescriptor ipd) {
candidateType = ipd.getIndexedPropertyType();
if (candidateName.equals(propertyName) &&
(candidateType.equals(propertyType) || candidateType.equals(propertyType.getComponentType()))) {
@@ -494,10 +493,9 @@ class ExtendedBeanInfo implements BeanInfo {
if (this == other) {
return true;
}
if (!(other instanceof IndexedPropertyDescriptor)) {
if (!(other instanceof IndexedPropertyDescriptor otherPd)) {
return false;
}
IndexedPropertyDescriptor otherPd = (IndexedPropertyDescriptor) other;
return (ObjectUtils.nullSafeEquals(getIndexedReadMethod(), otherPd.getIndexedReadMethod()) &&
ObjectUtils.nullSafeEquals(getIndexedWriteMethod(), otherPd.getIndexedWriteMethod()) &&
ObjectUtils.nullSafeEquals(getIndexedPropertyType(), otherPd.getIndexedPropertyType()) &&
@@ -168,10 +168,9 @@ final class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
if (this == other) {
return true;
}
if (!(other instanceof GenericTypeAwarePropertyDescriptor)) {
if (!(other instanceof GenericTypeAwarePropertyDescriptor otherPd)) {
return false;
}
GenericTypeAwarePropertyDescriptor otherPd = (GenericTypeAwarePropertyDescriptor) other;
return (getBeanClass().equals(otherPd.getBeanClass()) && PropertyDescriptorUtils.equals(this, otherPd));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -221,8 +221,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
*/
private PropertyValue mergeIfRequired(PropertyValue newPv, PropertyValue currentPv) {
Object value = newPv.getValue();
if (value instanceof Mergeable) {
Mergeable mergeable = (Mergeable) value;
if (value instanceof Mergeable mergeable) {
if (mergeable.isMergeEnabled()) {
Object merged = mergeable.merge(currentPv.getValue());
return new PropertyValue(newPv.getName(), merged);
@@ -423,9 +423,6 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
if (editor == null) {
// Find editor for superclass or interface.
for (Map.Entry<Class<?>, PropertyEditor> entry : this.customEditors.entrySet()) {
if (editor != null) {
break;
}
Class<?> key = entry.getKey();
if (key.isAssignableFrom(requiredType)) {
editor = entry.getValue();
@@ -435,6 +432,9 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
this.customEditorCache = new HashMap<>();
}
this.customEditorCache.put(requiredType, editor);
if (editor != null) {
break;
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -192,10 +192,9 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
if (this == other) {
return true;
}
if (!(other instanceof PropertyValue)) {
if (!(other instanceof PropertyValue otherPv)) {
return false;
}
PropertyValue otherPv = (PropertyValue) other;
return (this.name.equals(otherPv.name) &&
ObjectUtils.nullSafeEquals(this.value, otherPv.value) &&
ObjectUtils.nullSafeEquals(getSource(), otherPv.getSource()));
@@ -1,84 +0,0 @@
/*
* Copyright 2002-2019 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringValueResolver;
/**
* General utility methods for working with annotations in JavaBeans style.
*
* @author Rob Harrop
* @author Juergen Hoeller
* @since 2.0
* @deprecated as of 5.2, in favor of custom annotation attribute processing
*/
@Deprecated
public abstract class AnnotationBeanUtils {
/**
* Copy the properties of the supplied {@link Annotation} to the supplied target bean.
* Any properties defined in {@code excludedProperties} will not be copied.
* @param ann the annotation to copy from
* @param bean the bean instance to copy to
* @param excludedProperties the names of excluded properties, if any
* @see org.springframework.beans.BeanWrapper
*/
public static void copyPropertiesToBean(Annotation ann, Object bean, String... excludedProperties) {
copyPropertiesToBean(ann, bean, null, excludedProperties);
}
/**
* Copy the properties of the supplied {@link Annotation} to the supplied target bean.
* Any properties defined in {@code excludedProperties} will not be copied.
* <p>A specified value resolver may resolve placeholders in property values, for example.
* @param ann the annotation to copy from
* @param bean the bean instance to copy to
* @param valueResolver a resolve to post-process String property values (may be {@code null})
* @param excludedProperties the names of excluded properties, if any
* @see org.springframework.beans.BeanWrapper
*/
public static void copyPropertiesToBean(Annotation ann, Object bean, @Nullable StringValueResolver valueResolver,
String... excludedProperties) {
Set<String> excluded = (excludedProperties.length == 0 ? Collections.emptySet() :
new HashSet<>(Arrays.asList(excludedProperties)));
Method[] annotationProperties = ann.annotationType().getDeclaredMethods();
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(bean);
for (Method annotationProperty : annotationProperties) {
String propertyName = annotationProperty.getName();
if (!excluded.contains(propertyName) && bw.isWritableProperty(propertyName)) {
Object value = ReflectionUtils.invokeMethod(annotationProperty, ann);
if (valueResolver != null && value instanceof String) {
value = valueResolver.resolveStringValue((String) value);
}
bw.setPropertyValue(propertyName, value);
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -161,8 +161,7 @@ public abstract class BeanFactoryUtils {
public static String[] beanNamesForTypeIncludingAncestors(ListableBeanFactory lbf, ResolvableType type) {
Assert.notNull(lbf, "ListableBeanFactory must not be null");
String[] result = lbf.getBeanNamesForType(type);
if (lbf instanceof HierarchicalBeanFactory) {
HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
if (lbf instanceof HierarchicalBeanFactory hbf) {
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
String[] parentResult = beanNamesForTypeIncludingAncestors(
(ListableBeanFactory) hbf.getParentBeanFactory(), type);
@@ -199,8 +198,7 @@ public abstract class BeanFactoryUtils {
Assert.notNull(lbf, "ListableBeanFactory must not be null");
String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
if (lbf instanceof HierarchicalBeanFactory) {
HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
if (lbf instanceof HierarchicalBeanFactory hbf) {
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
String[] parentResult = beanNamesForTypeIncludingAncestors(
(ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
@@ -226,8 +224,7 @@ public abstract class BeanFactoryUtils {
public static String[] beanNamesForTypeIncludingAncestors(ListableBeanFactory lbf, Class<?> type) {
Assert.notNull(lbf, "ListableBeanFactory must not be null");
String[] result = lbf.getBeanNamesForType(type);
if (lbf instanceof HierarchicalBeanFactory) {
HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
if (lbf instanceof HierarchicalBeanFactory hbf) {
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
String[] parentResult = beanNamesForTypeIncludingAncestors(
(ListableBeanFactory) hbf.getParentBeanFactory(), type);
@@ -263,8 +260,7 @@ public abstract class BeanFactoryUtils {
Assert.notNull(lbf, "ListableBeanFactory must not be null");
String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
if (lbf instanceof HierarchicalBeanFactory) {
HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
if (lbf instanceof HierarchicalBeanFactory hbf) {
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
String[] parentResult = beanNamesForTypeIncludingAncestors(
(ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
@@ -289,8 +285,7 @@ public abstract class BeanFactoryUtils {
Assert.notNull(lbf, "ListableBeanFactory must not be null");
String[] result = lbf.getBeanNamesForAnnotation(annotationType);
if (lbf instanceof HierarchicalBeanFactory) {
HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
if (lbf instanceof HierarchicalBeanFactory hbf) {
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
String[] parentResult = beanNamesForAnnotationIncludingAncestors(
(ListableBeanFactory) hbf.getParentBeanFactory(), annotationType);
@@ -327,8 +322,7 @@ public abstract class BeanFactoryUtils {
Assert.notNull(lbf, "ListableBeanFactory must not be null");
Map<String, T> result = new LinkedHashMap<>(4);
result.putAll(lbf.getBeansOfType(type));
if (lbf instanceof HierarchicalBeanFactory) {
HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
if (lbf instanceof HierarchicalBeanFactory hbf) {
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
Map<String, T> parentResult = beansOfTypeIncludingAncestors(
(ListableBeanFactory) hbf.getParentBeanFactory(), type);
@@ -376,8 +370,7 @@ public abstract class BeanFactoryUtils {
Assert.notNull(lbf, "ListableBeanFactory must not be null");
Map<String, T> result = new LinkedHashMap<>(4);
result.putAll(lbf.getBeansOfType(type, includeNonSingletons, allowEagerInit));
if (lbf instanceof HierarchicalBeanFactory) {
HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
if (lbf instanceof HierarchicalBeanFactory hbf) {
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
Map<String, T> parentResult = beansOfTypeIncludingAncestors(
(ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
@@ -70,8 +70,8 @@ public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implem
*/
public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata) {
Assert.notNull(metadata, "AnnotationMetadata must not be null");
if (metadata instanceof StandardAnnotationMetadata) {
setBeanClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
if (metadata instanceof StandardAnnotationMetadata sam) {
setBeanClass(sam.getIntrospectedClass());
}
else {
setBeanClassName(metadata.getClassName());
@@ -25,7 +25,7 @@ import java.lang.annotation.Target;
/**
* Marks a constructor, field, setter method, or config method as to be autowired by
* Spring's dependency injection facilities. This is an alternative to the JSR-330
* {@link javax.inject.Inject} annotation, adding required-vs-optional semantics.
* {@link jakarta.inject.Inject} annotation, adding required-vs-optional semantics.
*
* <h3>Autowired Constructors</h3>
* <p>Only one constructor of any given bean class may declare this annotation with the
@@ -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.
@@ -22,10 +22,12 @@ import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
@@ -37,6 +39,8 @@ import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aot.generator.CodeContribution;
import org.springframework.aot.hint.ExecutableMode;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
@@ -48,9 +52,13 @@ import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.InjectionPoint;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.beans.factory.annotation.InjectionMetadata.InjectedElement;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.generator.AotContributingBeanPostProcessor;
import org.springframework.beans.factory.generator.BeanInstantiationContribution;
import org.springframework.beans.factory.generator.InjectionGenerator;
import org.springframework.beans.factory.support.LookupOverride;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
@@ -65,6 +73,7 @@ import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
@@ -75,8 +84,10 @@ import org.springframework.util.StringUtils;
* by default, Spring's {@link Autowired @Autowired} and {@link Value @Value}
* annotations.
*
* <p>Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation,
* <p>Also supports the common {@link jakarta.inject.Inject @Inject} annotation,
* if available, as a direct alternative to Spring's own {@code @Autowired}.
* Additionally, it retains support for the {@code javax.inject.Inject} variant
* dating back to the original JSR-330 specification (as known from Java EE 6-8).
*
* <h3>Autowired Constructors</h3>
* <p>Only one constructor of any given bean class may declare this annotation with
@@ -129,7 +140,7 @@ import org.springframework.util.StringUtils;
* @see Value
*/
public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
MergedBeanDefinitionPostProcessor, AotContributingBeanPostProcessor, PriorityOrdered, BeanFactoryAware {
protected final Log logger = LogFactory.getLog(getClass());
@@ -154,20 +165,30 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
/**
* Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's
* standard {@link Autowired @Autowired} and {@link Value @Value} annotations.
* <p>Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation,
* if available.
* <p>Also supports the common {@link jakarta.inject.Inject @Inject} annotation,
* if available, as well as the original {@code javax.inject.Inject} variant.
*/
@SuppressWarnings("unchecked")
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("jakarta.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.trace("'jakarta.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {
// jakarta.inject API not available - simply skip.
}
try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
logger.trace("'javax.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
// javax.inject API not available - simply skip.
}
}
@@ -177,7 +198,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
* setter methods, and arbitrary config methods.
* <p>The default autowired annotation types are the Spring-provided
* {@link Autowired @Autowired} and {@link Value @Value} annotations as well
* as JSR-330's {@link javax.inject.Inject @Inject} annotation, if available.
* as the common {@code @Inject} annotation, if available.
* <p>This setter property exists so that developers can provide their own
* (non-Spring-specific) annotation type to indicate that a member is supposed
* to be autowired.
@@ -193,7 +214,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
* setter methods, and arbitrary config methods.
* <p>The default autowired annotation types are the Spring-provided
* {@link Autowired @Autowired} and {@link Value @Value} annotations as well
* as JSR-330's {@link javax.inject.Inject @Inject} annotation, if available.
* as the common {@code @Inject} annotation, if available.
* <p>This setter property exists so that developers can provide their own
* (non-Spring-specific) annotation types to indicate that a member is supposed
* to be autowired.
@@ -243,8 +264,22 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
findInjectionMetadata(beanName, beanType, beanDefinition);
}
@Override
public BeanInstantiationContribution contribute(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = findInjectionMetadata(beanName, beanType, beanDefinition);
Collection<InjectedElement> injectedElements = metadata.getInjectedElements();
return (!ObjectUtils.isEmpty(injectedElements)
? new AutowiredAnnotationBeanInstantiationContribution(injectedElements)
: null);
}
private InjectionMetadata findInjectionMetadata(String beanName, Class<?> beanType, RootBeanDefinition beanDefinition) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
return metadata;
}
@Override
@@ -407,14 +442,6 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
return pvs;
}
@Deprecated
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
return postProcessProperties(pvs, bean, beanName);
}
/**
* 'Native' processing method for direct calls with an arbitrary target instance,
* resolving all of its fields and methods which are annotated with one of the
@@ -537,10 +564,9 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
* @param ann the Autowired annotation
* @return whether the annotation indicates that a dependency is required
*/
@SuppressWarnings("deprecation")
protected boolean determineRequiredStatus(MergedAnnotation<?> ann) {
return determineRequiredStatus(ann.<AnnotationAttributes> asMap(
mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
}
/**
@@ -594,8 +620,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
*/
@Nullable
private Object resolvedCachedArgument(@Nullable String beanName, @Nullable Object cachedArgument) {
if (cachedArgument instanceof DependencyDescriptor) {
DependencyDescriptor descriptor = (DependencyDescriptor) cachedArgument;
if (cachedArgument instanceof DependencyDescriptor descriptor) {
Assert.state(this.beanFactory != null, "No BeanFactory available");
return this.beanFactory.resolveDependency(descriptor, beanName, null, null);
}
@@ -796,6 +821,52 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
}
}
private static final class AutowiredAnnotationBeanInstantiationContribution implements BeanInstantiationContribution {
private final Collection<InjectedElement> injectedElements;
private final InjectionGenerator generator;
AutowiredAnnotationBeanInstantiationContribution(Collection<InjectedElement> injectedElements) {
this.injectedElements = injectedElements;
this.generator = new InjectionGenerator();
}
@Override
public void applyTo(CodeContribution contribution) {
this.injectedElements.forEach(element -> {
boolean isRequired = isRequired(element);
Member member = element.getMember();
analyzeMember(contribution, member);
contribution.statements().addStatement(this.generator.generateInjection(member, isRequired));
});
}
private boolean isRequired(InjectedElement element) {
if (element instanceof AutowiredMethodElement injectedMethod) {
return injectedMethod.required;
}
else if (element instanceof AutowiredFieldElement injectedField) {
return injectedField.required;
}
return true;
}
private void analyzeMember(CodeContribution contribution, Member member) {
if (member instanceof Method method) {
contribution.runtimeHints().reflection().registerMethod(method,
hint -> hint.setModes(ExecutableMode.INTROSPECT));
contribution.protectedAccess().analyze(member,
this.generator.getProtectedAccessInjectionOptions(member));
}
else if (member instanceof Field field) {
contribution.runtimeHints().reflection().registerField(field);
contribution.protectedAccess().analyze(member,
this.generator.getProtectedAccessInjectionOptions(member));
}
}
}
/**
* DependencyDescriptor variant with a pre-resolved target bean name.
@@ -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.
@@ -48,7 +48,7 @@ import org.springframework.util.Assert;
public abstract class BeanFactoryAnnotationUtils {
/**
* Retrieve all bean of type {@code T} from the given {@code BeanFactory} declaring a
* Retrieve all beans of type {@code T} from the given {@code BeanFactory} declaring a
* qualifier (e.g. via {@code <qualifier>} or {@code @Qualifier}) matching the given
* qualifier, or having a bean name matching the given qualifier.
* @param beanFactory the factory to get the target beans from (also searching ancestors)
@@ -90,9 +90,9 @@ public abstract class BeanFactoryAnnotationUtils {
Assert.notNull(beanFactory, "BeanFactory must not be null");
if (beanFactory instanceof ListableBeanFactory) {
if (beanFactory instanceof ListableBeanFactory lbf) {
// Full qualifier matching supported.
return qualifiedBeanOfType((ListableBeanFactory) beanFactory, beanType, qualifier);
return qualifiedBeanOfType(lbf, beanType, qualifier);
}
else if (beanFactory.containsBean(qualifier)) {
// Fallback: target bean at least found by bean name.
@@ -163,11 +163,10 @@ public abstract class BeanFactoryAnnotationUtils {
}
try {
Class<?> beanType = beanFactory.getType(beanName);
if (beanFactory instanceof ConfigurableBeanFactory) {
BeanDefinition bd = ((ConfigurableBeanFactory) beanFactory).getMergedBeanDefinition(beanName);
if (beanFactory instanceof ConfigurableBeanFactory cbf) {
BeanDefinition bd = cbf.getMergedBeanDefinition(beanName);
// Explicit qualifier metadata on bean definition? (typically in XML definition)
if (bd instanceof AbstractBeanDefinition) {
AbstractBeanDefinition abd = (AbstractBeanDefinition) bd;
if (bd instanceof AbstractBeanDefinition abd) {
AutowireCandidateQualifier candidate = abd.getQualifier(Qualifier.class.getName());
if (candidate != null) {
Object value = candidate.getAttribute(AutowireCandidateQualifier.VALUE_KEY);
@@ -177,8 +176,8 @@ public abstract class BeanFactoryAnnotationUtils {
}
}
// Corresponding qualifier on factory method? (typically in configuration class)
if (bd instanceof RootBeanDefinition) {
Method factoryMethod = ((RootBeanDefinition) bd).getResolvedFactoryMethod();
if (bd instanceof RootBeanDefinition rbd) {
Method factoryMethod = rbd.getResolvedFactoryMethod();
if (factoryMethod != null) {
Qualifier targetAnnotation = AnnotationUtils.getAnnotation(factoryMethod, Qualifier.class);
if (targetAnnotation != null) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2021 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.
@@ -91,11 +91,10 @@ public class CustomAutowireConfigurer implements BeanFactoryPostProcessor, BeanC
@SuppressWarnings("unchecked")
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (this.customQualifierTypes != null) {
if (!(beanFactory instanceof DefaultListableBeanFactory)) {
if (!(beanFactory instanceof DefaultListableBeanFactory dlbf)) {
throw new IllegalStateException(
"CustomAutowireConfigurer needs to operate on a DefaultListableBeanFactory");
}
DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;
if (!(dlbf.getAutowireCandidateResolver() instanceof QualifierAnnotationAutowireCandidateResolver)) {
dlbf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
}
@@ -106,8 +105,7 @@ public class CustomAutowireConfigurer implements BeanFactoryPostProcessor, BeanC
if (value instanceof Class) {
customType = (Class<? extends Annotation>) value;
}
else if (value instanceof String) {
String className = (String) value;
else if (value instanceof String className) {
customType = (Class<? extends Annotation>) ClassUtils.resolveClassName(className, this.beanClassLoader);
}
else {
@@ -32,6 +32,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -39,6 +40,8 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.beans.factory.generator.AotContributingBeanPostProcessor;
import org.springframework.beans.factory.generator.BeanInstantiationContribution;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.Ordered;
@@ -46,6 +49,7 @@ import org.springframework.core.PriorityOrdered;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
/**
@@ -66,19 +70,20 @@ import org.springframework.util.ReflectionUtils;
* init method and destroy method, respectively.
*
* <p>Spring's {@link org.springframework.context.annotation.CommonAnnotationBeanPostProcessor}
* supports the JSR-250 {@link javax.annotation.PostConstruct} and {@link javax.annotation.PreDestroy}
* supports the {@link jakarta.annotation.PostConstruct} and {@link jakarta.annotation.PreDestroy}
* annotations out of the box, as init annotation and destroy annotation, respectively.
* Furthermore, it also supports the {@link javax.annotation.Resource} annotation
* Furthermore, it also supports the {@link jakarta.annotation.Resource} annotation
* for annotation-driven injection of named beans.
*
* @author Juergen Hoeller
* @author Stephane Nicoll
* @since 2.5
* @see #setInitAnnotationType
* @see #setDestroyAnnotationType
*/
@SuppressWarnings("serial")
public class InitDestroyAnnotationBeanPostProcessor
implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable {
public class InitDestroyAnnotationBeanPostProcessor implements DestructionAwareBeanPostProcessor,
MergedBeanDefinitionPostProcessor, AotContributingBeanPostProcessor, PriorityOrdered, Serializable {
private final transient LifecycleMetadata emptyLifecycleMetadata =
new LifecycleMetadata(Object.class, Collections.emptyList(), Collections.emptyList()) {
@@ -117,7 +122,7 @@ public class InitDestroyAnnotationBeanPostProcessor
* methods to call after configuration of a bean.
* <p>Any custom annotation can be used, since there are no required
* annotation attributes. There is no default, although a typical choice
* is the JSR-250 {@link javax.annotation.PostConstruct} annotation.
* is the {@link jakarta.annotation.PostConstruct} annotation.
*/
public void setInitAnnotationType(Class<? extends Annotation> initAnnotationType) {
this.initAnnotationType = initAnnotationType;
@@ -128,7 +133,7 @@ public class InitDestroyAnnotationBeanPostProcessor
* methods to call when the context is shutting down.
* <p>Any custom annotation can be used, since there are no required
* annotation attributes. There is no default, although a typical choice
* is the JSR-250 {@link javax.annotation.PreDestroy} annotation.
* is the {@link jakarta.annotation.PreDestroy} annotation.
*/
public void setDestroyAnnotationType(Class<? extends Annotation> destroyAnnotationType) {
this.destroyAnnotationType = destroyAnnotationType;
@@ -146,8 +151,36 @@ public class InitDestroyAnnotationBeanPostProcessor
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
findInjectionMetadata(beanDefinition, beanType);
}
@Override
public BeanInstantiationContribution contribute(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
LifecycleMetadata metadata = findInjectionMetadata(beanDefinition, beanType);
if (!CollectionUtils.isEmpty(metadata.initMethods)) {
String[] initMethodNames = safeMerge(
beanDefinition.getInitMethodNames(), metadata.initMethods);
beanDefinition.setInitMethodNames(initMethodNames);
}
if (!CollectionUtils.isEmpty(metadata.destroyMethods)) {
String[] destroyMethodNames = safeMerge(
beanDefinition.getDestroyMethodNames(), metadata.destroyMethods);
beanDefinition.setDestroyMethodNames(destroyMethodNames);
}
return null;
}
private LifecycleMetadata findInjectionMetadata(RootBeanDefinition beanDefinition, Class<?> beanType) {
LifecycleMetadata metadata = findLifecycleMetadata(beanType);
metadata.checkConfigMembers(beanDefinition);
return metadata;
}
private String[] safeMerge(@Nullable String[] existingNames, Collection<LifecycleElement> detectedElements) {
Stream<String> detectedNames = detectedElements.stream().map(LifecycleElement::getIdentifier);
Stream<String> mergedNames = (existingNames != null
? Stream.concat(Stream.of(existingNames), detectedNames) : detectedNames);
return mergedNames.distinct().toArray(String[]::new);
}
@Override
@@ -394,10 +427,9 @@ public class InitDestroyAnnotationBeanPostProcessor
if (this == other) {
return true;
}
if (!(other instanceof LifecycleElement)) {
if (!(other instanceof LifecycleElement otherElement)) {
return false;
}
LifecycleElement otherElement = (LifecycleElement) other;
return (this.identifier.equals(otherElement.identifier));
}
@@ -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.
@@ -88,6 +88,14 @@ public class InjectionMetadata {
}
/**
* Return the {@link InjectedElement elements} to inject.
* @return the elements to inject
*/
public Collection<InjectedElement> getInjectedElements() {
return Collections.unmodifiableCollection(this.injectedElements);
}
/**
* Determine whether this metadata instance needs to be refreshed.
* @param clazz the current target class
@@ -304,10 +312,9 @@ public class InjectionMetadata {
if (this == other) {
return true;
}
if (!(other instanceof InjectedElement)) {
if (!(other instanceof InjectedElement otherElement)) {
return false;
}
InjectedElement otherElement = (InjectedElement) other;
return this.member.equals(otherElement.member);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -140,6 +140,8 @@ public final class ParameterResolutionDelegate {
* Due to a bug in {@code javac} on JDK versions prior to JDK 9, looking up
* annotations directly on a {@link Parameter} will fail for inner class
* constructors.
* <p>Note: Since Spring 6 may still encounter user code compiled with
* {@code javac 8}, this workaround is kept in place for the time being.
* <h4>Bug in javac in JDK &lt; 9</h4>
* <p>The parameter annotations array in the compiled byte code excludes an entry
* for the implicit <em>enclosing instance</em> parameter for an inner class
@@ -46,7 +46,7 @@ import org.springframework.util.ObjectUtils;
* against {@link Qualifier qualifier annotations} on the field or parameter to be autowired.
* Also supports suggested expression values through a {@link Value value} annotation.
*
* <p>Also supports JSR-330's {@link javax.inject.Qualifier} annotation, if available.
* <p>Also supports JSR-330's {@link jakarta.inject.Qualifier} annotation, if available.
*
* @author Mark Fisher
* @author Juergen Hoeller
@@ -66,13 +66,13 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
/**
* Create a new QualifierAnnotationAutowireCandidateResolver
* for Spring's standard {@link Qualifier} annotation.
* <p>Also supports JSR-330's {@link javax.inject.Qualifier} annotation, if available.
* <p>Also supports JSR-330's {@link jakarta.inject.Qualifier} annotation, if available.
*/
@SuppressWarnings("unchecked")
public QualifierAnnotationAutowireCandidateResolver() {
this.qualifierTypes.add(Qualifier.class);
try {
this.qualifierTypes.add((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Qualifier",
this.qualifierTypes.add((Class<? extends Annotation>) ClassUtils.forName("jakarta.inject.Qualifier",
QualifierAnnotationAutowireCandidateResolver.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
@@ -1,42 +0,0 @@
/*
* Copyright 2002-2018 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks a method (typically a JavaBean setter method) as being 'required': that is,
* the setter method must be configured to be dependency-injected with a value.
*
* <p>Please do consult the javadoc for the {@link RequiredAnnotationBeanPostProcessor}
* class (which, by default, checks for the presence of this annotation).
*
* @author Rob Harrop
* @since 2.0
* @see RequiredAnnotationBeanPostProcessor
* @deprecated as of 5.1, in favor of using constructor injection for required settings
* (or a custom {@link org.springframework.beans.factory.InitializingBean} implementation)
*/
@Deprecated
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Required {
}
@@ -1,230 +0,0 @@
/*
* Copyright 2002-2021 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.annotation;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.Conventions;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
* that enforces required JavaBean properties to have been configured.
* Required bean properties are detected through a Java 5 annotation:
* by default, Spring's {@link Required} annotation.
*
* <p>The motivation for the existence of this BeanPostProcessor is to allow
* developers to annotate the setter properties of their own classes with an
* arbitrary JDK 1.5 annotation to indicate that the container must check
* for the configuration of a dependency injected value. This neatly pushes
* responsibility for such checking onto the container (where it arguably belongs),
* and obviates the need (<b>in part</b>) for a developer to code a method that
* simply checks that all required properties have actually been set.
*
* <p>Please note that an 'init' method may still need to be implemented (and may
* still be desirable), because all that this class does is enforcing that a
* 'required' property has actually been configured with a value. It does
* <b>not</b> check anything else... In particular, it does not check that a
* configured value is not {@code null}.
*
* <p>Note: A default RequiredAnnotationBeanPostProcessor will be registered
* by the "context:annotation-config" and "context:component-scan" XML tags.
* Remove or turn off the default annotation configuration there if you intend
* to specify a custom RequiredAnnotationBeanPostProcessor bean definition.
*
* @author Rob Harrop
* @author Juergen Hoeller
* @since 2.0
* @see #setRequiredAnnotationType
* @see Required
* @deprecated as of 5.1, in favor of using constructor injection for required settings
* (or a custom {@link org.springframework.beans.factory.InitializingBean} implementation)
*/
@Deprecated
public class RequiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
/**
* Bean definition attribute that may indicate whether a given bean is supposed
* to be skipped when performing this post-processor's required property check.
* @see #shouldSkip
*/
public static final String SKIP_REQUIRED_CHECK_ATTRIBUTE =
Conventions.getQualifiedAttributeName(RequiredAnnotationBeanPostProcessor.class, "skipRequiredCheck");
private Class<? extends Annotation> requiredAnnotationType = Required.class;
private int order = Ordered.LOWEST_PRECEDENCE - 1;
@Nullable
private ConfigurableListableBeanFactory beanFactory;
/**
* Cache for validated bean names, skipping re-validation for the same bean.
*/
private final Set<String> validatedBeanNames = Collections.newSetFromMap(new ConcurrentHashMap<>(64));
/**
* Set the 'required' annotation type, to be used on bean property
* setter methods.
* <p>The default required annotation type is the Spring-provided
* {@link Required} annotation.
* <p>This setter property exists so that developers can provide their own
* (non-Spring-specific) annotation type to indicate that a property value
* is required.
*/
public void setRequiredAnnotationType(Class<? extends Annotation> requiredAnnotationType) {
Assert.notNull(requiredAnnotationType, "'requiredAnnotationType' must not be null");
this.requiredAnnotationType = requiredAnnotationType;
}
/**
* Return the 'required' annotation type.
*/
protected Class<? extends Annotation> getRequiredAnnotationType() {
return this.requiredAnnotationType;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
if (beanFactory instanceof ConfigurableListableBeanFactory) {
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
}
}
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
}
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
if (!this.validatedBeanNames.contains(beanName)) {
if (!shouldSkip(this.beanFactory, beanName)) {
List<String> invalidProperties = new ArrayList<>();
for (PropertyDescriptor pd : pds) {
if (isRequiredProperty(pd) && !pvs.contains(pd.getName())) {
invalidProperties.add(pd.getName());
}
}
if (!invalidProperties.isEmpty()) {
throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName));
}
}
this.validatedBeanNames.add(beanName);
}
return pvs;
}
/**
* Check whether the given bean definition is not subject to the annotation-based
* required property check as performed by this post-processor.
* <p>The default implementations check for the presence of the
* {@link #SKIP_REQUIRED_CHECK_ATTRIBUTE} attribute in the bean definition, if any.
* It also suggests skipping in case of a bean definition with a "factory-bean"
* reference set, assuming that instance-based factories pre-populate the bean.
* @param beanFactory the BeanFactory to check against
* @param beanName the name of the bean to check against
* @return {@code true} to skip the bean; {@code false} to process it
*/
protected boolean shouldSkip(@Nullable ConfigurableListableBeanFactory beanFactory, String beanName) {
if (beanFactory == null || !beanFactory.containsBeanDefinition(beanName)) {
return false;
}
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
if (beanDefinition.getFactoryBeanName() != null) {
return true;
}
Object value = beanDefinition.getAttribute(SKIP_REQUIRED_CHECK_ATTRIBUTE);
return (value != null && (Boolean.TRUE.equals(value) || Boolean.parseBoolean(value.toString())));
}
/**
* Is the supplied property required to have a value (that is, to be dependency-injected)?
* <p>This implementation looks for the existence of a
* {@link #setRequiredAnnotationType "required" annotation}
* on the supplied {@link PropertyDescriptor property}.
* @param propertyDescriptor the target PropertyDescriptor (never {@code null})
* @return {@code true} if the supplied property has been marked as being required;
* {@code false} if not, or if the supplied property does not have a setter method
*/
protected boolean isRequiredProperty(PropertyDescriptor propertyDescriptor) {
Method setter = propertyDescriptor.getWriteMethod();
return (setter != null && AnnotationUtils.getAnnotation(setter, getRequiredAnnotationType()) != null);
}
/**
* Build an exception message for the given list of invalid properties.
* @param invalidProperties the list of names of invalid properties
* @param beanName the name of the bean
* @return the exception message
*/
private String buildExceptionMessage(List<String> invalidProperties, String beanName) {
int size = invalidProperties.size();
StringBuilder sb = new StringBuilder();
sb.append(size == 1 ? "Property" : "Properties");
for (int i = 0; i < size; i++) {
String propertyName = invalidProperties.get(i);
if (i > 0) {
if (i == (size - 1)) {
sb.append(" and");
}
else {
sb.append(',');
}
}
sb.append(" '").append(propertyName).append('\'');
}
sb.append(size == 1 ? " is" : " are");
sb.append(" required for bean '").append(beanName).append('\'');
return sb.toString();
}
}

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