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
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
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
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
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
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
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
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
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
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
Attempting to create a large array in a SpEL expression can result in
an OutOfMemoryError. Although the JVM recovers from that, the error
message is not very helpful to the user.
This commit improves the diagnostics in SpEL for large array creation
by throwing a SpelEvaluationException with a meaningful error message
in order to improve diagnostics for the user.
Closes gh-28145
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
This commit improves the documentation for test execution events,
especially with regard to the fact that, by default, a
BeforeTestClassEvent is not published for the first test class using a
particular ApplicationContext.
This commit also introduces tests that verify the default behavior and
the ability to change the default behavior with a custom
TestExecutionListener that eagerly loads the context.
Closes gh-27757
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
This commit introduces Javadoc to explain the difference between
init/destroy method names when such methods are private, namely that a
private method is registered via its qualified method name; whereas, a
non-private method is registered via its simple name.
See gh-28083
Prior to this commit, `AsyncRestTemplate` would log errors (including
simple 404s) with WARN level. Such errors are quite common and should
not clutter logs.
This commit aligns the logging strategy with RestTemplate, using the
DEBUG level for such cases.
Fixes gh-28049
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
All Spring MVC exceptions from spring-web, now implement ErrorResponse
and expose HTTP error response information, including an RFC 7807 body.
See gh-27052