Commit d3fba6d49b introduced built-in pattern matching support for
method names in ControlFlowPointcut; however, it was still cumbersome
to extend ControlFlowPointcut with support for regular expressions
instead of simple pattern matching.
To address that, this commit introduces a variant of isMatch() that
accepts the pattern index instead of the pre-resolved method name
pattern. The default implementation retrieves the method name pattern
from the methodNamePatterns field and delegates to isMatch(String, String).
Subclasses can override the new isMatch(String, int) method to support
regular expressions, as can be seen in the example
RegExControlFlowPointcut class in ControlFlowPointcutTests.
See gh-31435
Prior to this commit, ControlFlowPointcut supported a single method
name which was matched exactly. Although it was possible to extend
ControlFlowPointcut to add support for pattern matching, it was a bit
cumbersome.
To address that, this commit introduces built-in pattern matching
support for method names in ControlFlowPointcut, analogous to the
pattern matching support in NameMatchMethodPointcut.
Specifically, a user can provide one or more method name patterns, and
the patterns will be matched against candidate method names using OR
semantics.
By default, the matching algorithm delegates to
PatternMatchUtils.simpleMatch(), but this can be overridden in
subclasses by overriding the new protected isMatch() method.
Closes gh-31435
This commit makes ControlFlowPointcut more open to subclasses by:
1. Making the ControlFlowPointcut#clazz field protected.
2. Making the ControlFlowPointcut#methodName field protected.
3. Introducing a protected incrementEvaluationCount() method.
Closes gh-27187
This commit adds Coroutines support for `@Cacheable`.
It also refines SimpleKeyGenerator to ignore Continuation
parameters (Kotlin does not allow to have the same method
signature with both suspending and non-suspending variants)
and refines
org.springframework.aop.framework.CoroutinesUtils.awaitSingleOrNull
in order to wrap plain value to Mono.
Closes gh-31412
For equivalence, we only need to compare the preInstantiationPointcut
fields since they include the declaredPointcut fields. In addition, we
should not compare the aspectInstanceFactory fields since
LazySingletonAspectInstanceFactoryDecorator does not implement equals().
See gh-31238
This commit expands the scope of equality checks in the implementation
of equals() for PerTargetInstantiationModelPointcut to include all
fields instead of just the pointcut expression for the declared
pointcut.
See gh-31238
The introduction of AdvisedSupport.AdvisorKeyEntry in Spring Framework
6.0.10 resulted in a regression regarding caching of CGLIB generated
proxy classes. Specifically, equality checks for the proxy class cache
became based partially on identity rather than equivalence. For
example, if an ApplicationContext was configured to create a
class-based @Transactional proxy, a second attempt to create the
ApplicationContext resulted in a duplicate proxy class for the same
@Transactional component.
On the JVM this went unnoticed; however, when running Spring
integration tests within a native image, if a test made use of
@DirtiesContext, a second attempt to create the test
ApplicationContext resulted in an exception stating, "CGLIB runtime
enhancement not supported on native image." This is because Test AOT
processing only refreshes a test ApplicationContext once, and the
duplicate CGLIB proxy classes are only requested in subsequent
refreshes of the same ApplicationContext which means that duplicate
proxy classes are not tracked during AOT processing and consequently
not included in a native image.
This commit addresses this regression as follows.
- AdvisedSupport.AdvisorKeyEntry is now based on the toString()
representations of the ClassFilter and MethodMatcher in the
corresponding Pointcut instead of the filter's and matcher's
identities.
- Due to the above changes to AdvisorKeyEntry, ClassFilter and
MethodMatcher implementations are now required to implement equals(),
hashCode(), AND toString().
- Consequently, the following now include proper equals(), hashCode(),
and toString() implementations.
- CacheOperationSourcePointcut
- TransactionAttributeSourcePointcut
- PerTargetInstantiationModelPointcut
Closes gh-31238
This commit deprecates the various nullSafeHashCode methods taking array
types as they are superseded by Arrays.hashCode now. This means that
the now only remaining nullSafeHashCode method does not trigger a
warning only if the target type is not an array. At the same time, there
are multiple use of this method on several elements, handling the
accumulation of hash codes.
For that reason, this commit also introduces a nullSafeHash that takes
an array of elements. The only difference between Objects.hash is that
this method handles arrays.
The codebase has been reviewed to use any of those two methods when it
is possible.
Closes gh-29051
This commit allows a custom code fragment to provide the code to
create a bean without relying on ConstructorResolver. This is especially
important for use cases that derive from the default behaviour and
provide an instance supplier with the regular runtime scenario.
This is a breaking change for code fragments providing a custom
implementation of the related methods. As it turns out, almost all of
them did not need the Executable argument. Configuration class parsing
is the exception, where it needs to provide a different constructor in
the case of the proxy. To make this use case possible,
InstanceSupplierCodeGenerator has been made public.
Closes gh-31117
This commit adds support for Kotlin Coroutines to Spring AOP
by leveraging CoroutinesUtils#invokeSuspendingFunction in
AopUtils#invokeJoinpointUsingReflection to convert it to the
equivalent Publisher return value, like in other parts of Spring
Framework.
That allows method interceptors with Reactive support to process
related return values.
CglibAopProxy#processReturnType and JdkDynamicAopProxy#invoke
take care of the conversion from the Publisher return value
to Kotlin Coroutines.
Reactive transactional and HTTP service interface support
have been refined to leverage those new generic capabilities.
Closes gh-22462
Java 12 introduced java.lang.Class#componentType() as a shortcut for
getComponentType().
Since we started using arrayType() in fe5560400c, this commit switches
to componentType() for consistent API usage style.