Prior to this change, roughly 5% (~300 out of 6000+) of files under the
source tree had CRLF line endings as opposed to the majority which have
LF endings.
This change normalizes these files to LF for consistency going forward.
Command used:
$ git ls-files | xargs file | grep CRLF | cut -d":" -f1 | xargs dos2unix
Issue: SPR-5608
Prior to this change, ScheduledAnnotationBeanPostProcessor found any
@Scheduled methods against the ultimate targetClass for a given bean
and then attempted to invoke that method against the bean instance. In
cases where the bean instance was in fact a JDK proxy, this attempt
would fail because the proxy is not an instance of the target class.
Now SABPP still attempts to find @Scheduled methods against the target
class, but subsequently checks to see if the bean is a JDK proxy, and if
so attempts to find the corresponding method on the proxy itself. If it
cannot be found (e.g. the @Scheduled method was declared only at the
concrete class level), an appropriate exception is thrown, explaining to
the users their options: (a) use proxyTargetClass=true and go with
subclass proxies which won't have this problem, or (b) pull the
@Scheduled method up into an interface.
Issue: SPR-8651
Prior to this change, an assumption was made in
AbstractAutowireCapableBeanFactory that any factory-method would have
zero parameters. This may not be the case in @Bean methods.
We now look for the factory-method by name in a more flexible fashion
that accomodates the possibility of method parameters.
There remains at least one edge cases here where things could still fail,
for example a @Configuration class could have two FactoryBean-returning
methods of the same name, but each with different generic FactoryBean
types and different parameter lists. In this case, the implementation
may infer and return the wrong object type, as it currently returns
the first match for the given factory-method name. The complexity cost
of ensuring that this never happens is not likely worth the trouble
given the very low likelihood of such an arrangement.
Issue: SPR-8762
In order to determine why Ehcache classloading errors occur after
upgrading to 4.2.0.Final.
To demonstrate this error, uncomment the 4.2.0.Final dependency in
ivy.xml and run `ant test` within the .context module.
Prior to this change, to specify two or more annotation include/exclude
filters, one would declare @ComponentScan as follows:
@ComponentScan(basePackages="example.scannable",
useDefaultFilters=false,
includeFilters={
@Filter(MyStereotype.class),
@Filter(MyComponent.class)
})
This was because @Filter's 'value' attribute accepted exactly one
argument.
Now, any given @Filter may accept one or more value arguments, allowing
for more concise @ComponentScan declarations:
@ComponentScan(basePackages="example.scannable",
useDefaultFilters=false,
includeFilters=@Filter({MyStereotype.class, MyComponent.class}))
Supplying multiple arguments in this way assumes that they are the same
type of filter, e.g. ANNOTATION, ASSIGNABLE_TYPE, or CUSTOM. To declare
multiple *different* types of filters, multiple @Filter annotations are
still required, e.g.:
@ComponentScan(
includeFilters={
@Filter(type=ANNOTATION, value=MyStereotype.class),
@Filter(type=ASSIGNABLE_TYPE, value={Foo.class, Bar.class})
})
Note that specifying zero arguments, e.g. @Filter({}) is nonsensical; it
will have no effect on component scanning, but does not raise an error.
Issue: SPR-8881
For clarity, add @Target({}) to definition of @Filter, constraining it
to complex annotation composition only; i.e. it cannot be placed on
any element, only within annotations, e.g.
@ComponentScan(includeFilters=@Filter(...))
is legal, while
@Filter
public class MyType { }
is not.
Also, widen @Retention from SOURCE to RUNTIME, even though it is not
technically necessary, as all parsing of @Filter annotations happens via
ASM, i.e. at the source level. This change is made primarily for
consistency (@ComponentScan's Retention is RUNTIME) and in avoidance of
potential confusion or surprise on the part of those casually browsing
the code.
Prior to this change, a @Configuration classes that @ComponentScan
themselves would result in a ConflictingBeanDefinitionException.
For example:
package com.foo.config;
@Configuration
@ComponentScan("com.foo");
public class AppConfig {
// ...
}
This resulted in a ConflictingBeanDefinitionException that users have
typically worked around in the following fashion:
package com.foo.config;
@Configuration
@ComponentScan(basePackages="com.foo",
excludeFilters=@Filter(value=ANNOTATION_TYPE, type=Configuration.class);
public class AppConfig {
// ...
}
This is obviously more verbose and cumbersome than would be desirable,
and furthermore potentially too constraining as it prohibits the ability
to include other legitimate @Configuration classes via scanning.
The exception was being thrown because of a logic problem in
ClassPathBeanDefinitionScanner. The bean definition for AppConfig gets
registered once by the user (e.g. when constructing an
AnnotationConfigApplicationContext), then again when performing the
component scan for 'com.foo'. Prior to this change,
ClassPathBeanDefinitionScanner's #isCompatible returned false if the new
bean definition was anything other than an AnnotatedBeanDefinition. The
intention of this check is really to see whether the new bean definition
is a *scanned* bean definition, i.e. the result of a component-scanning
operation. If so, then it becomes safe to assume that the original bean
definition is the one that should be kept, as it is the one explicitly
registered by the user.
Therefore, the fix is as simple as narrowing the instanceof check from
AnnotatedBeanDefinition to its ScannedGenericBeanDefinition subtype.
Note that this commit partially reverts changes introduced in SPR-8307
that explicitly caught ConflictingBeanDefinitionExceptions when
processing recursive @ComponentScan definitions, and rethrew as a
"CircularComponentScanException. With the changes in this commit,
such CBDEs will no longer occur, obviating the need for this check and
for this custom exception type altogether.
Issue: SPR-8808, SPR-8307
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