Similar to @ExceptionHandler but for message processing. Such a method
can send messages to both the message broker channel and the client
channel provided the client is subscribed to the target destination.
The "system" STOMP session is established at startup and can be used
to send messages without a client session, e.g. to support broadcasting
from a REST/HTTP handler method.
MessageHolder holds the currently processed message in a ThreadLocal,
which allows PubSubMessageBuilder to automatically add a session id
to messages to be sent.
Rename to PubSubHeaderAccessor and StompHeaderAccessor
Move the renamed classes to support packages
Remove fromPayloadAndHeaders from MessageBuilder, just use
withPayload(..).copyHeaders(..) instead.
The use of an AtomicBoolean and no lock meant that it was possible
for a message to be queued and then never be flushed and sent to the
broker:
1. On t1, a message is received and isConnected is false. The message
will be queued.
2. On t2, CONNECTED is received from the broker. isConnected is set
to true, the queue is drained and the queued messages are forwarded
3. On t1, the message is added to the queue
To fix this, checking that isConnected is false (step 1 above) and the
queueing of a message (step 3 above) need to be performed as a unit
so that the flushing of the queued messages can't be interleaved. This
is achieved by synchronizing on a monitor and performing steps 1
and 3 and synchronizing on the same monitor while performing step 2.
The monitor is held while the messages are actually being forwarded
to the broker. An alternative would be to drain the queue into
a local variable, release the monitor, and then forward the messages.
The main advantage of this alternative is that the monitor is held for
less time. It also reduces the theoretical risk of deadlock by not
holding the monitor while making an alien call. The downside of the
alternative is that it may lead to messages being forwarded out of
order. For this reason the alternative approach was rejected.
When an annotated handler returns a Message from a @SubscribeEvent
or @MessageMapping method and it contains no destination in its
headers, use the received message's destination as the response
message's destination.
Without generics, extending AbstractPubSubChannelRegistry and using
a custom Message type requires some unpleasant casting and suppression
of warnings. By genericizing PubSubChannelRegistry and
AbstractPubSubChannelRegistry these problems can be avoided.
Prior to this commit, the longValue() in HeaderResultMatchers added the
expected response header name to generated assertion failure messages;
however, both string() methods did not. This made it more difficult to
analyze the cause of failed tests.
Furthermore, while investigating a solution for this issue it became
apparent that longValue() throws a NullPointerException if the response
does not contain the specified header.
This commit addresses these issues as follows:
- All methods in HeaderResultMatchers now include the response header
name in generated assertion failure messages.
- HeaderResultMatchers.longValue() now avoids NullPointerExceptions by
explicitly asserting that the response contains the specified header.
- The unit tests in HeaderAssertionTests have been expanded to test
most foreseeable use cases.
Issue: SPR-10659
This commit refactors ContextLoaderUtilsTests into
AbstractContextLoaderUtilsTests and several specialized subclasses in
order to reduce to the growing complexity of ContextLoaderUtilsTests.
Prior to this commit, the active bean definition profiles to use when
loading an ApplicationContext for tests could only be configured
declaratively (i.e., via hard-coded values supplied to the 'value' or
'profiles' attribute of @ActiveProfiles).
This commit makes it possible to programmatically configure active bean
definition profiles in tests via a new ActiveProfileResolver interface.
Custom resolvers can be registered via a new 'resolver' attribute
introduced in @ActiveProfiles.
Overview of changes:
- Introduced a new ActiveProfilesResolver API.
- Added a 'resolver' attribute to @ActiveProfiles.
- Updated ContextLoaderUtils.resolveActiveProfiles() to support
ActiveProfilesResolvers.
- Documented these new features in the reference manual.
- Added new content to the reference manual regarding the
'inheritProfiles' attribute of @ActiveProfiles
- Removed the use of <lineannotation> Docbook markup in the testing
chapter of the reference manual for Java code examples in order to
allow comments to have proper syntax highlighting in the generated
HTML and PDF.
Issue: SPR-10338
Prior to this commit the Spring Framework did not provide a public means
for scanning for available server ports. However, the Spring Framework
internally used a FreePortScanner in integration tests within its own
test suite. Furthermore, Spring Integration 2.2 provides similar support
in a SocketUtils class in the spring-integration-test module.
This commit introduces SocketUtils in spring-core to replace the
FreePortScanner which was previously only used internally within
Spring's test suite. This new implementation is inspired by both Spring
Framework's FreePortScanner and Spring Integration's SocketUtils and
consequently attempts to merge the best of both previous
implementations.
Issue: SPR-8032
To improve compatibility between Spring's messaging classes and
Spring Integration, the type of Message that is created has been made
pluggable through the introduction of a factory abstraction;
MessageFactory.
By default a MessageFactory is provided that will create
org.springframework.messaging.GenericMessage instances, however this
can be replaced with an alternative implementation. For example,
Spring Integration can provide an implementation that creates
org.springframework.integration.message.GenericMessage instances.
This control over the type of Message that's created allows messages
to flow from Spring messaging code into Spring Integration code without
any need for conversion. In further support of this goal,
MessageChannel, MessageHandler, and SubscribableChannel have been
genericized to make the Message type that they deal with more
flexible.
Introduce new ConfigurationCondition interface allowing more
fine-grained control for @Conditional when used with @Configuration
beans.
Primarily added so that the evaluation of conditions that inspect bean
definitions can be deferred until all @Configuration classes have been
parsed.
Issue: SPR-10534
Update ConfigurationClassParser to fall-back to ASM parsing if standard
annotation processing fails. This change allows @Conditional annotations
that refer to missing classes to work.
This commit also introduces a new inner SourceClass object that
encapsulates the conditional logic required when reading the source
classes.
Issue: SPR-10646
The Javadoc for several methods in HttpSession specifies that an
IllegalStateException must be thrown if the method is called on an
invalidated session; however, Spring's MockHttpSession did not implement
this behavior consistently prior to this commit.
This commit therefore ensures that the following methods in
MockHttpSession properly throw an IllegalStateException as defined in
the Servlet specification.
- long getCreationTime()
- long getLastAccessedTime()
- Object getAttribute(String)
- Object getValue(String)
- Enumeration<String> getAttributeNames()
- String[] getValueNames()
- void setAttribute(String, Object)
- void putValue(String , Object)
- void removeAttribute(String)
- void removeValue(String)
- void invalidate()
- boolean isNew()
Issue: SPR-7659
Prior to this commit it was possible for the method and requestURI
fields in MockHttpServletRequest to be set to null.
This commit ensures that the method and requestURI fields are internally
stored as empty strings if the user sets them to a null value.
Issue: SPR-10643