Equivalent to <context:spring-configured/>.
Also update @EnableLoadTimeWeaving Javadoc and spring-configured XSD
documentation to reflect.
Issue: SPR-7888
3.1 M2 introduced a regression that causes false positives during
@Configuration class candidate checks. Now performing a call to
AnnotationMetadata#isInterface in addition to checks for @Component and
@Bean annotations when determining whether a candidate is a 'lite'
configuration class. Annotations are in the end interfaces, so both
are filtered out at once.
Issue: SPR-8761
Prior to this change, any instantiation of an
AnnotationConfigApplicationContext would trigger the creation of three
StandardEnvironment objects: one for the ApplicationContext, one for the
AnnotatedBeanDefinitionReader, and one for the
ClassPathBeanDefinitionScanner.
The latter two are immediately swapped out when the ApplicationContext
delegates its environment to these subordinate objects anyway. Not only
is it inefficient to create these two extra Environments, it creates
confusion when debug-level logging is turned on. From the user's
perspective and in practice, there is only one Environment; logging
should reflect that.
This change ensures that only one Environment object is ever created for
a given ApplicationContext. If an AnnotatedBeanDefinitionReader or
ClassPathBeanDefinitionScanner are used in isolation, e.g. against a
plain BeanFactory/BeanDefinitionRegistry, then they will still create
their own local StandardEnvironment object.
All public API compatibility is preserved; new constructors have been
added where necessary to accommodate passing an Environment directly
to ABDR ar CPBDS.
Allowing beans of primitive type to be looked up via getBean(Class), or
to be injected using @Autowired or @Injected or @Resource. Prior to
these changes, an attempt to lookup or inject a bean of, for example,
type boolean would fail because all spring beans are Objects, regardless
of initial type due to the way that ObjectFactory works.
Now these attempts to lookup or inject primitive types work, thanks to
simple changes in AbstractBeanFactory using ClassUtils#isAssignable
methods instead of the built-in Class#isAssignableFrom. The former takes
into account primitives and their object wrapper types, whereas the
latter does not.
The need to declare, look up or inject primitive-typed beans is probably
low -- how often does one need a bean of type boolean or int after all?.
Prior to the introduction of @Bean methods in Spring 3.0, it was not
possible in practice to register primitive beans, so this issue never
came up. Now that one can declare primitive-typed beans, it does make
sense that we properly support by-type lookup and injection without
forcing the user to work with object wrappers.
Issue: SPR-8874
The registration of more than one ConfigurationClassPostProcessor
results in the double-enhancement of @Configuration classes, i.e. a
two-deep CGLIB subclass hierarchy is created.
As a side-effect of changes introduced in 3.1 M2 fixing SPR-8080, this
behavior now results in an infinite loop at CGLIB callback processing
time, leading to a StackOverflowException which is then suppressed by
the container, and ultimately results in the user being presented with
an unintuitive "Bean 'x' is not already in creation" exception.
This fix introduces a marker interface 'EnhancedConfiguration' to be
implemented by all generated @Configuration subclasses. The
configuration class enhancer can then behave in an idempotent fashion
by checking to see whether a candidate @Configuration class is already
assignable to this type i.e. already enhanced and ignore it if so.
Naturally, users should avoid registering more than one
ConfigurationClassPostProcessor, but this is not always possible. As
with the case in point, SPR-8824 originates from problems with
spring-data-neo4j, which explicitly registers its own
ConfigurationClassPostProcessor. The user has little control over this
arrangement, so it is important that the framework is defensive as
described above.
Issue: SPR-8824
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.
Also eliminate all 'cache definition' language in favor of
'cache operation' in comments, method and parameter names (most
classes had already been refactored to this effect).
Unfortunately creates a large diff due to whitespace changes as well as
false attribution of authorship from a git/svn 'blame' perspective.
Be sure to perform diffs using `git diff -w` or `svn diff -w` when
reviewing recent changes to these sources to ignore all whitespace.
In favor of existing #setCacheOperationSources(CacheOperationSource...)
Also polish Javadoc throughout, replacing stale references to
CacheDefinitionSource where appropriate as well as other minor changes
Facilitates type-safe programmatic configuration from @Bean methods:
@Bean
public CacheManager cacheManager() {
SimpleCacheManager cm = new SimpleCacheManager();
cm.setCaches(Arrays.asList(
new ConcurrentMapCache("default"),
new ConcurrentMapCache("primary"),
new ConcurrentMapCache("secondary")
));
return cm;
}
Prior to this change, the code above would have raised errors on the
Arrays.asList() call because it returns a Collection<? extends Cache>
as opposed to Collection<Cache>.
After this change, AbstractCacheManager expects
Collection<? extends Cache> throughout.
Refactored getConfig => getApplicationContext such that subclasses have
control over the type of ApplicationContext used by the base class
tests. Done in anticipation of @EnableCaching tests that will favor use
of AnnotationConfigApplicationContext
Also updated all use of ClassPathXmlApplictionContext to
GenericXmlApplicationContext, which is generally preferred.
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.
Anywhere the value of a destroy method may be expressed, specifying
the value "(inferred)" now indicates that the container should attempt
to automatically discover a destroy method. This functionality is
currently limited to detecting public, no-arg methods named 'close';
this is particularly useful for commonly used types such as Hibernate
SessionFactory most JDBC DataSource implementations, JMS connection
factories, and so forth.
This special value is captured as the constant
AbstractBeanDefinition#INFER_METHOD, which in turn serves as the default
value of the @Bean#destroyMethod attribute.
For example in the following case
@Bean
public BasicDataSource dataSource() { ... }
the container will automatically detect BasicDataSource#close and invoke
it when the enclosing ApplicationContext is closed. This is exactly
equivalent to
@Bean(destroyMethod="(inferred)")
public BasicDataSource dataSource() { ... }
A user may override this inference-by-default convention simply by
specifying a different method
@Bean(destroyMethod="myClose")
public MyBasicDataSource dataSource() { ... }
or, in the case of a bean that has an otherwise inferrable 'close'
method, but the user wishes to disable handling it entirely, an empty
string may be specified
@Bean(destroyMethod="")
public MyBasicDataSource dataSource() { ... }
The special destroy method name "(inferred)" may also be specified in
an XML context, e.g.
<bean destroy-method="(inferred)">
or
<beans default-destroy-method="(inferred)">
Note that "(inferred)" is the default value for @Bean#destroyMethod,
but NOT for the destroy-method and default-destroy-method attributes
in the spring-beans XML schema.
The principal reason for introducing this feature is to avoid forcing
@Configuration class users to type destroyMethod="close" every time a
closeable bean is configured. This kind of boilerplate is easily
forgotten, and this simple convention means the right thing is done
by default, while allowing the user full control over customization or
disablement in special cases.
Issue: SPR-8751
Add BridgeMethodResolver#isJava6VisibilityBridgeMethodPair to
distinguish between (a) bridge methods introduced in Java 6 to
compensate for inheriting public methods from non-public superclasses
and (b) bridge methods that have existed since Java 5 to accommodate
return type covariance and generic parameters.
In the former case, annotations should be looked up from the original
bridged method (SPR-7900). In the latter, the annotation should be
looked up against the bridge method itself (SPR-8660).
As noted in the Javadoc for the new method, see
http://stas-blogspot.blogspot.com/2010/03/java-bridge-methods-explained.html
for a useful description of the various types of bridge methods, as
well as http://bugs.sun.com/view_bug.do?bug_id=6342411, the bug fixed in
Java 6 resulting in the introduction of 'visibility bridge methods'.
Issue: SPR-8660, SPR-7900
Remove all convenience variants of #findAllAnnotationAttributes and
refactor the remaining method to accept a MetadataReaderFactory
instead of creating its own SimpleMetadataReaderFactory internally.
This allows clients to use non-default class loaders as well as
customize the particular MetadataReaderFactory to be used (e.g.
'simple' vs 'caching', etc).
Issue: SPR-8752