Certain edge cases around return type covariance can trigger an
IntrospectionException when trying to create a new PropertyDescriptor;
particularly around the addition of write methods with parameter types
that do not match read method return types.
These type mismatch exceptions are raised during normal Introspector
operations as well (i.e. without ExtendedBeanInfo in the mix), but
the Introspector intentionally supresses them. In covariance cases,
there is often already a suitable write method present, e.g. discovered
in a supertype or superinterface, that, with the benefit of bridge
methods works just fine in practice at runtime. That is to say, in
these suppression cases, the rejection of the write method is 'OK' in
that there is already a write method present that can handle a call.
ExtendedBeanInfo now mirrors this suppression behavior, but does issue
a WARN-level log message to let the user know.
An important effect of this change is that ExtendedBeanInfo now modifies
the delegate BeanInfo object, whereas previously it did not. In practice
this probably matters very little, but it is a design change worth
noting. The reason for this change was to avoid the need to create new
PropertyDescriptors wherever possible. It was discovered that by updating
existing PDs, one can avoid these IntrospectionExceptions a greater
percentage of the time.
Issue: SPR-8806
The UriComponentsBuilder instance passed into the method is initialized
with current request information including host, scheme, port, context
path, and the servlet mapping's literal part.
Also added shortcut methods to buildAndExpand in UriComponentsBuilder.
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
The initial solution kept these three in full sync at all times:
contentType field, characterEncoding field, 'Content-Type' header.
That is correct behavior, however it breaks existing tests that rely
on contentType and characterEncoding being equal to exactly what
they were set to.
For example, consider:
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
Ideally both contentType and the 'Content-Type' header would now be
"text/plain;charset=UTF-8". However, existing tests would expect
that contentType is equal to "text/plain".
To avoid breaking existing tests, contentType and characterEncoding
will continue to be equal to exactly what they were set to while
the 'Content-Type' header will always include both the content
type and the charset.
The only exception to this rule is when a 'Content-Type' header
is set explicitly, the contentType and characterEncoding fields will
be updated accordingly, possibly overriding the existing values.
The Content-Type header and the contentType field in HttpServletRequest/Response
are now always in sync. When a header is added the contentType field is updated
as well and vice versa.
Similarly when the Content-Type header or the contentType field includes a charset
field, the character encoding is updated and vice versa.
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.
This was removed once previously but accidentally re-introduced later.
The 'correct' version of spring-cache-3.1.xsd lives in spring-context
as opposed to here in spring-context-support.
Also placed .gitignore file within src/main/resources such that the
now-empty directory does not get pruned in git environments, which will
otherwise cause 'missing source folder' errors within Eclipse/IDEA.
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.