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
The AbstractHttpMessageConverter was using the requested Content-Type
rather than the actual response Content-Type to determine the length
of the content. This can lead to a problem when a controller returns
a ResponseEntity with a Content-Type header that ignores (overrides)
the requested Content-Type. The fix ensures that actual response
Content-Type is the one used both to write to the response and to
determine the length of the content.
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.
Properties such as 'spring.profiles.active' cannot be specified at the
command line under Bash and other shells due to variable naming
constraints. This change allows for exchanging underscores for periods
as well as capitalizing property names for more idiomatic naming when
dealing with environment variables.
For example, Spring will respect equally either of the following:
spring.profiles.active=p1 java -classpath ... MyApp
SPRING_PROFILES_ACTIVE=p1 java -classpath ... MyApp
The former is not possible under Bash, while the latter is. No code or
configuration changes are required; SystemEnvironmentPropertySource
adapts for these varations automatically.
SystemEnvironmentPropertySource is added by default as
"systemEnvironment" to StandardEnvironment and all subtypes, taking the
place of the plain MapPropertySource that was in use before this change.
Issue: SPR-8869
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
Currently the combine method consolidates "/*" and "/hotel"
into "/hotel". However if the first pattern contains URI template
variables, the consolidation seems wrong. The fix is to prevent
the consolidation if the first pattern contains "{".