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
Current STS version of Spring (3.0.5) does not contain
the BeanUtils.instantiateClass(Class<?>, Class<T>) signature
that was added in 3.1.0, therefore NoSuchMethodErrors are
being thrown when STS classloads and delegates to
3.1.0 NamespaceHandler and BeanDefinitionParser implementations
on the user project classpath.
In this case, it's AbstractSpecificationBeanDefinitionParser
doing the calling to the unknown new method. In this specific
example, reverting back to the old single-arg signature is actually
not a problem, because it does accept Class<T> and returns an
instance of type T, which was the desired behavior in the first
place.
The newer signature remains in order to accommodate callers
who do not know the generic type of the Class to be instantiated
(i.e. Class<?>), but do know the type that it should be assignable
to -- this becomes the second argument Class<T>, and an instance
of type T is returned (if indeed it is assignable to the specified
type; otherwise IllegalArgumentException.
Defensively catch NoSuchMethodError when calling BDPD.getEnvironment()
and supply a DefaultEnvironment if not available.
Replace the single-arg constructor for BDPD and deprecate, preserving
binary compat particularly for Spring Integration who instantiates
this class directly, which is unusual.
Revert changes to ParserContext, ReaderContext, and XmlReaderContext
These changes cause cross-version incompatibilities at tooling time
-- for instance, an STS version that ships with Spring 3.0.5
classloads the ParserContext defined in that version, whereas it
classloads NamespaceHandlers and BeanDefinitionParsers (by default)
from the user application classpath, which may be building against
3.1.0. If so, the changes introduced to these types in 3.1.0 are
incompatible with expectations in the 3.0.5 world and cause all
manner of problems. In this case, it was NoSuchMethodError due to
the newly-added XmlReaderContext.getProblemReporter() method; also
IncompatibleClassChangeError due to the introduction of the
ComponentRegistrar interface on ParserContext.
Each of these problems have been mitigated, though the solutions
are not ideal. The method mentioned has been removed, and instead
the problemReporter field is now accessed reflectively.
ParserContext now no longer implements ComponentRegistrar, and
rather a ComponentRegistrarAdapter class has been introduced that
passes method calls through to a ParserContext delegate.
Introduce AbstractSpecificationBeanDefinitionParser
AbstractSpecificationBeanDefinitionParser has been introduced in
order to improve the programming model for BeanDefinitionParsers
that have been refactored to the new FeatureSpecification model.
This new base class and it's template method implementation of
parse/doParse ensure that common concerns like (1) adapting a
ParserContext into a SpecificationContext, (2) setting source and
source name on the specification, and (3) actually executing the
specification are all managed by the base class. The subclass
implementation of doParse need only actually parse XML, populate
and return the FeatureSpecification object. This change removed
the many duplicate 'createSpecificationContext' methods that had
been lingering.
Minor improvement to BeanDefinitionReaderUtils API
Introduced new BeanDefinitionReaderUtils#registerWithGeneratedName
variant that accepts BeanDefinition as opposed to
AbstractBeanDefinition, as BeanDefinition is all that is actually
necessary to satisfy the needs of the method implementation. The
latter variant accepting AbstractBeanDefinition has been deprecated
but remains intact and delegates to the new variant in order to
maintain binary compatibility.
This change broke binary compatibility as evidenced by running
the greenhouse test suite and finding that Spring Integration's
AbstractConsumerEndpointParser.parseInternal fails with
NoSuchMethodError when trying to invoke.
Introduce FeatureSpecification interface and implementations
FeatureSpecification objects decouple the configuration of
spring container features from the concern of parsing XML
namespaces, allowing for reuse in code-based configuration
(see @Feature* annotations below).
* ComponentScanSpec
* TxAnnotationDriven
* MvcAnnotationDriven
* MvcDefaultServletHandler
* MvcResources
* MvcViewControllers
Refactor associated BeanDefinitionParsers to delegate to new impls above
The following BeanDefinitionParser implementations now deal only
with the concern of XML parsing. Validation is handled by their
corresponding FeatureSpecification object. Bean definition creation
and registration is handled by their corresponding
FeatureSpecificationExecutor type.
* ComponentScanBeanDefinitionParser
* AnnotationDrivenBeanDefinitionParser (tx)
* AnnotationDrivenBeanDefinitionParser (mvc)
* DefaultServletHandlerBeanDefinitionParser
* ResourcesBeanDefinitionParser
* ViewControllerBeanDefinitionParser
Update AopNamespaceUtils to decouple from XML (DOM API)
Methods necessary for executing TxAnnotationDriven specification
(and eventually, the AspectJAutoProxy specification) have been
added that accept boolean arguments for whether to proxy
target classes and whether to expose the proxy via threadlocal.
Methods that accepted and introspected DOM Element objects still
exist but have been deprecated.
Introduce @FeatureConfiguration classes and @Feature methods
Allow for creation and configuration of FeatureSpecification objects
at the user level. A companion for @Configuration classes allowing
for completely code-driven configuration of the Spring container.
See changes in ConfigurationClassPostProcessor for implementation
details.
See Feature*Tests for usage examples.
FeatureTestSuite in .integration-tests is a JUnit test suite designed
to aggregate all BDP and Feature* related tests for a convenient way
to confirm that Feature-related changes don't break anything.
Uncomment this test and execute from Eclipse / IDEA. Due to classpath
issues, this cannot be compiled by Ant/Ivy at the command line.
Introduce @FeatureAnnotation meta-annotation and @ComponentScan impl
@FeatureAnnotation provides an alternate mechanism for creating
and executing FeatureSpecification objects. See @ComponentScan
and its corresponding ComponentScanAnnotationParser implementation
for details. See ComponentScanAnnotationIntegrationTests for usage
examples
Introduce Default[Formatting]ConversionService implementations
Allows for convenient instantiation of ConversionService objects
containing defaults appropriate for most environments. Replaces
similar support originally in ConversionServiceFactory (which is now
deprecated). This change was justified by the need to avoid use
of FactoryBeans in @Configuration classes (such as
FormattingConversionServiceFactoryBean). It is strongly preferred
that users simply instantiate and configure the objects that underlie
our FactoryBeans. In the case of the ConversionService types, the
easiest way to do this is to create Default* subtypes. This also
follows convention with the rest of the framework.
Minor updates to util classes
All in service of changes above. See diffs for self-explanatory
details.
* BeanUtils
* ObjectUtils
* ReflectionUtils