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
Renamed TransactionManagementConfigurer#createTransactionManager()
to #annotationDrivenTransactionManager() to better reflect the fact
that the implemented method is optionally eligible for @Bean annotation.
See Javadoc for details.
This reverts commit da914bcfb4 and also
removes the use of Ordered#NOT_ORDERED from EnableTransactionManagement
and ProxyTransactionManagementConfiguration in favor of defaulting to
Ordered#LOWEST_PRIORITY, which is actually the default that results
when no 'order' attribute is specified in XML.
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
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.
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
* Environment now extends PropertyResolver
* Environment no longer exposes resolver and sources
* PropertySource is String,Object instead of String,String
* PropertySource no longer assumes enumerability of property names
* Introduced EnumerablePropertySource for those that do have enumerable property names
All existing *Aware interfaces have been refactored to extend this
new marker interface, serving two purposes:
* Easy access to a type hierarchy that can answer the question
"What *Aware interfaces are available?", without requiring
text-based searches. Also clearly excludes false positives like
TargetClassAware and ParamAware, which while similarly named,
are not semantically similar to traditional *Aware interfaces
in Spring.
* Minor potential performance improvements in
AbstractAutowireCapableBeanFactory and
ApplicationContextAwareProcessor. Both have blocks of sequential
instanceof checks in order to invoke any *Aware interface callback
methods. For a bean that implements none of these interfaces,
the whole sequence can be avoided by guarding first with
if (bean instanceof Aware) {
...
}
Implementors of custom *Aware-style interfaces (and presumably
the BeanPostProcessors that handle them), are encouraged to refactor to
extending this interface for consistency with the framework as well as
the points above.
Decomposed Environment interface into PropertySources, PropertyResolver
objects
Environment interface and implementations are still present, but
simpler.
PropertySources container aggregates PropertySource objects;
PropertyResolver provides search, conversion, placeholder
replacement. Single implementation for now is
PropertySourcesPlaceholderResolver
Renamed EnvironmentAwarePropertyPlaceholderConfigurer to
PropertySourcesPlaceholderConfigurer
<context:property-placeholder/> now registers PSPC by default, else
PPC if systemPropertiesMode* settings are involved
Refined configuration and behavior of default profiles
See Environment interface Javadoc for details
Added Portlet implementations of relevant interfaces:
* DefaultPortletEnvironment
* PortletConfigPropertySource, PortletContextPropertySource
* Integrated each appropriately throughout Portlet app contexts
Added protected 'createEnvironment()' method to AbstractApplicationContext
Subclasses can override at will to supply a custom Environment
implementation. In practice throughout the framework, this is how
Web- and Portlet-related ApplicationContexts override use of the
DefaultEnvironment and swap in DefaultWebEnvironment or
DefaultPortletEnvironment as appropriate.
Introduced "stub-and-replace" behavior for Servlet- and Portlet-based
PropertySource implementations
Allows for early registration and ordering of the stub, then
replacement with actual backing object at refresh() time.
Added AbstractApplicationContext.initPropertySources() method to
support stub-and-replace behavior. Called from within existing
prepareRefresh() method so as to avoid impact with
ApplicationContext implementations that copy and modify AAC's
refresh() method (e.g.: Spring DM).
Added methods to WebApplicationContextUtils and
PortletApplicationContextUtils to support stub-and-replace behavior
Added comprehensive Javadoc for all new or modified types and members
Added XSD documentation for all new or modified elements and attributes
Including nested <beans>, <beans profile="..."/>, and changes for
certain attributes type from xsd:IDREF to xsd:string
Improved fix for detecting non-file based Resources in
PropertiesLoaderSupport (SPR-7547, SPR-7552)
Technically unrelated to environment work, but grouped in with
this changeset for convenience.
Deprecated (removed) context:property-placeholder
'system-properties-mode' attribute from spring-context-3.1.xsd
Functionality is preserved for those using schemas up to and including
spring-context-3.0. For 3.1, system-properties-mode is no longer
supported as it conflicts with the idea of managing a set of property
sources within the context's Environment object. See Javadoc in
PropertyPlaceholderConfigurer, AbstractPropertyPlaceholderConfigurer
and PropertySourcesPlaceholderConfigurer for details.
Introduced CollectionUtils.toArray(Enumeration<E>, A[])
Work items remaining for 3.1 M2:
Consider repackaging PropertySource* types; eliminate internal use
of SystemPropertyUtils and deprecate
Further work on composition of Environment interface; consider
repurposing existing PlaceholderResolver interface to obviate need
for resolve[Required]Placeholder() methods currently in Environment.
Ensure configurability of placeholder prefix, suffix, and value
separator when working against an AbstractPropertyResolver
Add JNDI-based Environment / PropertySource implementatinos
Consider support for @Profile at the @Bean level
Provide consistent logging for the entire property resolution
lifecycle; consider issuing all such messages against a dedicated
logger with a single category.
Add reference documentation to cover the featureset.
Branch in question is 'env' branch from git://git.springsource.org/sandbox/cbeams.git; merged into
git-svn repository with:
git merge -s recursive -Xtheirs --no-commit env
No merge conflicts, but did need to
git rm spring-build
prior to committing.
With this change, Spring 3.1.0 development is now happening on SVN
trunk. Further commits to the 3.0.x line will happen in an as-yet
uncreated SVN branch. 3.1.0 snapshots will be available
per the usual nightly CI build from trunk.