SPR-6460 Added "phase" attribute to the JMS "listener-container" element.

This commit is contained in:
Mark Fisher 2009-11-27 17:42:30 +00:00
parent b444220564
commit dc24944cd9
4 changed files with 47 additions and 2 deletions

View File

@ -44,6 +44,8 @@ class JmsListenerContainerParser extends AbstractListenerContainerParser {
private static final String ERROR_HANDLER_ATTRIBUTE = "error-handler";
private static final String PHASE_ATTRIBUTE = "phase";
private static final String CACHE_ATTRIBUTE = "cache";
@ -107,6 +109,11 @@ class JmsListenerContainerParser extends AbstractListenerContainerParser {
new RuntimeBeanReference(destinationResolverBeanName));
}
String phase = containerEle.getAttribute(PHASE_ATTRIBUTE);
if (StringUtils.hasText(phase)) {
containerDef.getPropertyValues().add("phase", phase);
}
String cache = containerEle.getAttribute(CACHE_ATTRIBUTE);
if (StringUtils.hasText(cache)) {
if (containerType.startsWith("simple")) {

View File

@ -233,6 +233,16 @@
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="phase" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The lifecycle phase within which this container should start and stop. The lower
the value the earlier this container will start and the later it will stop. The
default is Integer.MAX_VALUE meaning the container will start as late as possible
and stop as soon as possible.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>

View File

@ -37,6 +37,7 @@ import org.springframework.beans.factory.parsing.EmptyReaderEventListener;
import org.springframework.beans.factory.parsing.PassThroughSourceExtractor;
import org.springframework.beans.factory.parsing.ReaderEventListener;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.Phased;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jca.endpoint.GenericMessageEndpointManager;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
@ -144,6 +145,19 @@ public class JmsNamespaceHandlerTests extends TestCase {
assertNull(defaultErrorHandler);
}
public void testPhases() {
int phase1 = getPhase("listener1");
int phase2 = getPhase("listener2");
int phase3 = getPhase("listener3");
int phase4 = getPhase("listener4");
int defaultPhase = getPhase(DefaultMessageListenerContainer.class.getName() + "#0");
assertEquals(99, phase1);
assertEquals(99, phase2);
assertEquals(Integer.MAX_VALUE, phase3);
assertEquals(Integer.MAX_VALUE, phase4);
assertEquals(Integer.MAX_VALUE, defaultPhase);
}
private MessageListener getListener(String containerBeanName) {
DefaultMessageListenerContainer container = this.context.getBean(containerBeanName, DefaultMessageListenerContainer.class);
return (MessageListener) container.getMessageListener();
@ -154,6 +168,14 @@ public class JmsNamespaceHandlerTests extends TestCase {
return (ErrorHandler) new DirectFieldAccessor(container).getPropertyValue("errorHandler");
}
public int getPhase(String containerBeanName) {
Object container = this.context.getBean(containerBeanName);
if (!(container instanceof Phased)) {
throw new IllegalStateException("Container '" + containerBeanName + "' does not implement Phased.");
}
return ((Phased) container).getPhase();
}
public void testComponentRegistration() {
assertTrue("Parser should have registered a component named 'listener1'", context.containsComponentDefinition("listener1"));
assertTrue("Parser should have registered a component named 'listener2'", context.containsComponentDefinition("listener2"));

View File

@ -7,12 +7,13 @@
<jms:listener-container connection-factory="testConnectionFactory" task-executor="testTaskExecutor"
destination-resolver="testDestinationResolver" message-converter="testMessageConverter"
transaction-manager="testTransactionManager" error-handler="testErrorHandler">
transaction-manager="testTransactionManager" error-handler="testErrorHandler" phase="99">
<jms:listener id="listener1" destination="testDestination" ref="testBean1" method="setName"/>
<jms:listener id="listener2" destination="testDestination" ref="testBean2" method="setName" response-destination="responseDestination"/>
</jms:listener-container>
<jms:listener-container>
<!-- TODO: remove the task-executor reference once issue with blocking on stop is resolved -->
<jms:listener-container task-executor="testTaskExecutor">
<jms:listener destination="testDestination" ref="testBean3"/>
</jms:listener-container>
@ -54,4 +55,9 @@
<bean id="testBean3" class="org.springframework.jms.config.JmsNamespaceHandlerTests$TestMessageListener"/>
<!-- TODO: remove this once issue with blocking on stop is resolved -->
<bean id="lifecycleProcessor" class="org.springframework.context.support.DefaultLifecycleProcessor">
<property name="timeoutPerShutdownPhase" value="0"/>
</bean>
</beans>