org.springframework.context.config.FeatureSpecification |
Known Indirect Subclasses |
Interface to be implemented by objects that specify the configuration of a particular feature of the Spring container e.g., component-scanning, JMX MBean exporting, AspectJ auto-proxying, annotation-driven transaction management, and so on.
Many features of the Spring container can be configured using either XML or annotations.
As one example, Spring's component scanning feature may be configured using
either the <context:component-scan>
XML element or (as of Spring 3.1) the
@ComponentScan
annotation. These two options are equivalent to one another, and users may
choose between them as a matter of convention or preference. Fundamentally, both are declarative
mechanisms for specifying how the Spring container should be configured. A FeatureSpecification
object, then, is a way of representing this configuration information independent
of its original source format be it XML, annotations, or otherwise.
A FeatureSpecification
is responsible for validating itself
.
For example, a component-scanning specification would check that at least one base package has
been specified, and otherwise register a Problem
with a ProblemReporter
. Taking
this approach as opposed to throwing exceptions allows for maximum tooling and error reporting
flexibility.
A FeatureSpecificationExecutor
is used to carry out the instructions within a populated
FeatureSpecification
; this is where the "real work" happens. In the case of component scanning
as above, it is within a FeatureSpecificationExecutor
that a bean definition scanner is created,
configured and invoked against the base packages specified.
FeatureSpecification
objects may be populated and executed by Spring XML namespace element
parsers on order to separate the concerns of XML parsing from Spring bean definition creation and
registration. This type of use is mostly a framework-internal matter. More interesting to end users is
the use of FeatureSpecification
objects within @FeatureConfiguration
classes and their
@Feature
methods. This functionality is new in Spring 3.1 and is the logical evolution of Spring's
Java-based configuration support first released in Spring 3.0 (see @Configuration
classes and
@Bean
methods). The primary goal of Feature
-related support is to round out this
Java-based support and allow users to configure all aspects of the Spring-container without requiring
the use of XML. See "design notes" below for an example of this kind of use.
FeatureSpecification
implementationsThe public API of a FeatureSpecification
should be designed for maximum ease of use
within @Feature
methods. Traditional JavaBean-style getters and setters should be dropped
for a more fluent style that allows for method chaining. Consider the following example of a
@Feature
method:
@Feature public TxAnnotationDriven tx(PlatformTransactionManager txManager) { return new TxAnnotationDriven(txManager).proxyTargetClass(true); }Notice how the creation and configuration of the
TxAnnotationDriven
specification is
concise and reads well. This is facilitated by mutator methods that always return the
specification object's 'this' reference, allowing for method chaining. A secondary design goal
of this approach is that the resulting code tends to mirror corresponding XML namespace
declarations, which most Spring users are already familiar with. For example, compare the
code above with its XML counterpart:
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
Typically, a user will call only the constructor and 'mutator' methods of a specification
object. The accessor/getter methods, however, are typically called only by the specification's
executor
for the purpose of populating and registering
bean definitions with the Spring container. For this reason, it is recommended that accessor
methods be given package-private visibility. This creates a better experience for users from
an IDE content-assist point of view as they will see only the public mutator methods, reducing
any possible confusion.
Implementations should take care to allow for use of string-based bean names, placeholder
("${...}"
) and SpEL ("#{...}
) expressions wherever they may be useful.
While it is generally desirable to refer to dependent beans in pure Java, in certain cases a
user may wish or need to refer to a bean by name. For example, the TxAnnotationDriven
specification
referenced above allows for specifying its transaction-manager reference by String
or by
PlatformTransactionManager
reference. Such strings should always be candidates for placeholder
replacement and SpEL evaluation for maximum configurability as well as parity with the feature set
available in Spring XML. With regard to SpEL expressions, users should assume that only expressions
evaluating to a bean name will be supported. While it is technically possible with SpEL to resolve
a bean instance, specification executors will not support such use unless explicitly indicated.
See the Javadoc for @FeatureConfiguration
classes and @Feature
methods for
information on their lifecycle and semantics.
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Execute this specification instance, carrying out the instructions
specified within.
| |||||||||||
Validate this specification instance to ensure all required properties
have been set, including checks on mutually exclusive or mutually
dependent properties.
|
Execute this specification instance, carrying out the instructions
specified within. Should work by delegating to an underlying
FeatureSpecificationExecutor
for proper separation of concerns.
Validate this specification instance to ensure all required properties have been set, including checks on mutually exclusive or mutually dependent properties. May in some cases modify the state of the specification e.g., instantiating types specified as strings.