This change is in support of certain polymorphism cases in
@Configuration class inheritance hierarchies. Consider the following
scenario:
@Configuration
public abstract class AbstractConfig {
public abstract Object bean();
}
@Configuration
public class ConcreteConfig {
@Override@Bean
public BeanPostProcessor bean() { ... }
}
ConcreteConfig overrides AbstractConfig's #bean() method with a
covariant return type, in this case returning an object of type
BeanPostProcessor. It is critically important that the container
is able to detect the return type of ConcreteConfig#bean() in order
to instantiate the BPP at the right point in the lifecycle.
Prior to this change, the container could not do this.
AbstractAutowireCapableBeanFactory#getTypeForFactoryMethod called
ReflectionUtils#getAllDeclaredMethods, which returned Method objects
for both the Object and BeanPostProcessor signatures of the #bean()
method. This confused the implementation sufficiently as not to
choose a type for the factory method at all. This means that the
BPP never gets detected as a BPP.
The new method being introduced here, #getUniqueDeclaredMethods, takes
covariant return types into account, and filters out duplicates,
favoring the most specific / narrow return type.
Additionally, it filters out any CGLIB 'rewritten' methods, which
is important in the case of @Configuration classes, which are
enhanced by CGLIB. See the implementation for further details.
Consolidating internal bean name and aspect class name constats within
AnnotationConfigUtils to allow access from both the context.config
and context.annotation packages without creating a relationship between
the two of them (they are unrelated leaf nodes in the packaging
currently).
The .transaction module does not have a similar utils class and already
has a relationship from transaction.config -> transaction.annotation,
so placing the constants in .annotation.TransactionManagementCapability
to be referenced by .config.AnnotationDrivenBeanDefinitionParser
Allows @Enable* a layer of indirection for deciding which @Configuration
class(es) to @Import.
The @Import annotation may now accept @Configuration class literals
and/or ImportSelector class literals.
@Configuration classes may implement ImportAware in order to be injected
with the AnnotationMetadata of their @Import'ing class.
Includes the introduction of a new PriorityOrdered
ImportAwareBeanPostProcessor that handles injection of the
importing class metadata.
Includes the introduction of AnnotationUtils#findAllAnnotationAttributes
to support iterating through all annotations declared on a given type
and interrogating each for the presence of a meta-annotation. See tests
for details.
The overloading necessary to preserve the new signature as well as
the old causes ambiguities leading to deprecation warnings in some
caller scenarios.
Previously errors were being raised when trying to inject @Value
annotated paramaters such as:
@Feature
public FeatureSpec feature(@Value("#{environment['foo']}") String foo) {
return new FeatureSpec(foo);
}
This is not so much because dependency resolution of @Value-annotated
types was failing, but rather because the 'early bean reference'
proxying mechanism was throwing an exception if any final type was
detected as a parameter. This is of course because final types are
non-subclassable by CGLIB. On review, however, it's obvious that
certain final types must be allowed for injection. @Value injection
is an obvious one, but the rarer case of a Spring bean of type String
or int is another.
The explicit guard against final types as parameters to @Feature methods
has been removed. Final types are still checked for, however, and if
found, no proxing is attempted. The dependency is immediately resolved
against the current BeanFactory and injected into the @Feature method.
This means that @Value injection, @Qualifier injection, etc all work
as expected, but does mean that premature bean instantiation may occur
if a user unwittingly injects non-String, non-primitive final bean types
as @Feature method parameters.
Issue: SPR-7974
CGLIB-enhanced @Configuration subclasses now implement DisposableBean
such that Enhancer.registerStaticCallbacks(subclass, null) is invoked
on container shutdown. This ensures that garbage collection can work
properly and avoids memory consumption issues for applications that
create and destroy many application contexts within the same JVM.
Issue: SPR-7901
context:property-placeholder extends 'propertyPlaceholder' type
defintion once again. This relationship was inadvertently removed in
3.1 M1, and the effect was that XML tooling would raise errors on
use of attributes like 'location'.
The updated schema has also been published to
http://www.springframework.org/schema/context/spring-context-3.1.xsd
Issue: SPR-8037
Prove that injection of special container types such as ResourceLoader,
BeanFactory, etc already works with the current implementation of
@Feature methods.
Issue: SPR-7975