Also introduces consistent use of getBean(Class) for similar use cases across the framework, accepting a locally unique target bean even if further matching beans would be available in parent contexts (in contrast to BeanFactoryUtils.beanOfType's behavior).
Issue: SPR-10160
As of Spring 3.0.4, we were trying to expose the target method signature as transaction name. Unfortunately, the algorithm called the ClassUtils.getMostSpecificMethod helper method which performs a quite expensive reflective search. As of this commit, we're simply concatenating the target class name with the method name, accepting the use of the concrete target class (which is arguably more meaningful for monitoring anyway) even when the method implementation actually sits on a base class.
Issue: SPR-9802
Commit 3f387eb9cf refactored and
deprecated TransactionAspectUtils, moving its #qualifiedBeanOfType
and related methods into BeanFactoryUtils. This created a package cycle
between beans.factory and beans.factory.annotation due to use of the
beans.factory.annotation.Qualifier annotation in these methods.
This commit breaks the package cycle by introducing
beans.factory.annotation.BeanFactoryAnnotationUtils and moving these
@Qualifier-related methods to it. It is intentionally similar in name
and style to the familiar BeanFactoryUtils class for purposes of
discoverability.
There are no backward-compatibilty concerns associated with this change
as the cycle was introduced, caught and now fixed before a release.
Issue: SPR-9443
Backport-Issue: SPR-6847
Backport-Commit: a4b00c732b
TransactionAspectUtils contains a number of methods useful in
retrieving a bean by type+qualifier. These methods are functionally
general-purpose save for the hard coding of PlatformTransactionManager
class literals throughout.
This commit generifies these methods and moves them into
BeanFactoryUtils primarily in anticipation of their use by async method
execution interceptors and aspects when performing lookups for qualified
executor beans e.g. via @Async(qualifier).
The public API of TransactionAspectUtils remains backward compatible;
all methods within have been deprecated, and all calls to those methods
throughout the framework refactored to use the new BeanFactoryUtils
variants instead.
Issue: SPR-9443
Backport-Issue: SPR-6847
Backport-Commit: 096693c46f
- Drop 'expectedType' parameter from #getClass and #getEnum methods and
rely on compiler inference based on type of assigned variable, e.g.
public @interface Example {
Color color();
Class<? extends UserType> userType();
int order() default 0;
}
AnnotationAttributes example =
AnnotationUtils.getAnnotationAttributes(Example.class, true, true);
Color color = example.getEnum("color");
Class<? extends UserType> userType = example.getClass("userType");
or in cases where there is no variable assignment (and thus no
inference possible), use explicit generic type, e.g.
bean.setColor(example.<Color>getEnum("color"));
- Rename #get{Int=>Number} and update return type from int to
<N extends Number>, allowing invocations such as:
int order = example.getNumber("order");
These changes reduce the overall number of methods exposed by
AnnotationAttributes, while at the same time providing comprehensive
access to all possible annotation attribute types -- that is, instead of
requiring explicit #getInt, #getFloat, #getDouble methods, the
single #getNumber method is capabable of handling them all, and without
any casting required. And the obvious additional benefit is more concise
invocation as no redundant 'expectedType' parameters are required.
Uses of AnnotationMetadata#getAnnotationAttributes throughout the
framework have been updated to use the new AnnotationAttributes API in
order to take advantage of the more concise, expressive and type-safe
methods there.
All changes are binary compatible to the 3.1.0 public API, save
the exception below.
A minor binary compatibility issue has been introduced in
AbstractCachingConfiguration, AbstractAsyncConfiguration and
AbstractTransactionManagementConfiguration when updating their
protected Map<String, Object> fields representing annotation attributes
to use the new AnnotationAttributes API. This is a negligible breakage,
however, as the likelilhood of users subclassing these types is very
low, the classes have only been in existence for a short time (further
reducing the likelihood), and it is a source-compatible change given
that AnnotationAttributes is assignable to Map<String, Object>.
Prior to this change, roughly 5% (~300 out of 6000+) of files under the
source tree had CRLF line endings as opposed to the majority which have
LF endings.
This change normalizes these files to LF for consistency going forward.
Command used:
$ git ls-files | xargs file | grep CRLF | cut -d":" -f1 | xargs dos2unix
Issue: SPR-5608
Separate concerns of @Configuration class selection from the need to
register certain infrastructure beans such as auto proxy creators.
Prior to this change, ImportSelector implementations were responsible
for both of these concerns, leading to awkwardness and duplication.
Also introduced in this change is ImportBeanDefinitionRegistrar and
two implementations, AutoProxyRegistrar and AspectJAutoProxyRegistrar.
See the refactored implementations of CachingConfigurationSelector,
TransactionManagementConfigurationSelector to see the former;
AspectJAutoProxyConfigurationSelector to see the latter.
ImportSelector and ImportBeanDefinitionRegistrar are both handled as
special-case arguments to the @Import annotation within
ConfigurationClassParser.
These refactorings are important because they ensure that Spring users
will be able to understand and extend existing @Enable* annotations
and their backing ImportSelector and @Configuration classes, as well
as create their own with a minimum of effort.
There was some question about whether enabling subclass proxies via
proxyTargetClass / proxy-target-class settings would break annotation-
based demarcation of joinpoints due to inability to discover those
annotations in various scenarios. The provided tests prove that in
any conceivable case, these annotations (@Transactional, at least)
are discovered in a consistent fashion, meaning that switching proxy
strategies should be transparent to the application and honor
intended annotation semantics.
Removed formal deprecation warnings for AbstractSingletonFactoryBean and
its TransactionProxyFactoryBean and CacheProxyFactoryBean subclasses.
This is principally because TPFB is still used by Grails and could
conceivably be used to good effect by any third-party framework in a
similar fashion. CPFB is new with 3.1, but similar use is predictable.
Deprecations have been replaced by strong recommendations that users
avoid these types in modern Spring applications and favor the use of
namespaces and annotatinos, such as tx: and @Transactional (around
since Spring 2.x) and cache: and @Cacheable.
Issue: SPR-8680, SPR-8686
Cite original inspiriation by Domain-Driven Design, but make clear the
flexible and general-purpose nature of Spring's stereotype annotations
such as @Repository and @Service.
Also update @Repository Javadoc with more explicit instructions about
switching on exception translation through use of
PersistenceExceptionTranslationPostProcessor, and update PETPP Javadoc
for style as well as concrete examples of 'resource factories' that
implement the PersistenceExceptionTranslator interface
Issue: SPR-8691
Prior to this change, @EnableTransactionManagement (via the
ProxyTransactionManagementConfiguration class) did not properly
register its auto-proxy creator through the usual AopConfigUtils
methods. It was trying to register the APC as a normal @Bean method,
but this causes issues (SPR-8494) with the logic in
AopConfigUtils#registerOrEscalateApcAsRequired, which expects the APC
bean definition to have a beanClassName property. When the APC is
registered via a @Bean definition, it is actually a
factoryBean/factoryMethod situation with no directly resolvable
beanClass/beanClassName.
To solve this problem, ImportSelector#selectImports has been refactored
to accept an ImportSelector.Context instance. This object contains the
AnnotationMetadata of the importing class as well as the enclosing
BeanDefinitionRegistry to allow for the kind of conditional bean
registration necessary here. In this case, the bean definition that
must be registered conditionally is that of the auto-proxy creator.
It should only be registered if AdviceMode == PROXY, and thus the
ImportSelector is an appropriate place to make this happen. It must
happen as a BeanDefinition (rather than a @Bean method) for
compatibility with AopConfigUtils, and working with the
BeanDefinitionRegistry API allows for that. This change does mean that
in certain cases like this one, #selectImports has container modifying
side effects. Documentation has been updated to reflect.
Issue: SPR-8411, SPR-8494
@PostConstruct added to ProxyTransactionManagementConfiguration cases
ConcurrentModificationException (as detailed previously in SPR-8397.
Backing out for now until a better solution can be devised.
This reverts commit 235b729514.
Prior to this change, @EnableTransactionManagement (via the
ProxyTransactionManagementConfiguration class) did not properly
register its auto-proxy creator through the usual AopConfigUtils
methods. It was trying to register the APC as a normal @Bean method,
but this causes issues (SPR-8494) with the logic in
AopConfigUtils#registerOrEscalateApcAsRequired, which expects the APC
bean definition to have a beanClassName property. When the APC is
registered via a @Bean definition, it is actually a
factoryBean/factoryMethod situation with no directly resolvable
beanClass/beanClassName.
Rather than trying to rework how AopConfigUtils works, a @PostConstruct
method has been added to ProxyTransactionManagementConfiguration to call
the usual AopConfigUtils registration methods.
Issue: SPR-8411, SPR-8494