J'ai configuré une configuration de ressort pour JMS. Les choses fonctionnent bien, sauf que je n'arrive pas à l'obtenir en chargement paresseux (notez le default-lazy-init vrai dans le code ci-dessous). Si je commente le jmsContainer (DMLC) de ma config ci-dessous, le chargement paresseux fonctionne comme prévu. Sinon, il va instancier le DMLC, qui à son tour crée la file d'attente et la fabrique de connexions.Printemps 3.0 paresseux-init pas honoré pour DefaultMessageListenerContainer?
Qu'est-ce qui me manque?
jmsContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
default-lazy-init="true">
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
<prop key="java.naming.provider.url">t3:localhost:7001</prop>
</props>
</property>
</bean>
<bean id="queue" class="org.springframework.jndi.JndiObjectFactoryBean"
p:jndiTemplate-ref="jndiTemplate" p:jndiName="jms/queue"/>
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"
p:jndiTemplate-ref="jndiTemplate" p:jndiName="jms/connectionfactory"/>
<bean id="jmsDestinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver"
p:jndiTemplate-ref="jndiTemplate" p:cache="true" />
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"
p:autoStartup="false"
p:destination-ref="queue"
p:destinationResolver-ref="jmsDestinationResolver"
p:connectionFactory-ref="connectionFactory"
p:messageListener-ref="queueListener" />
<bean id="queueListener" class="com.blah.QueueListener"/>
</beans>
Et le test que je utilise pour conduire, DummyTest.java:
package blah;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:jmsContext.xml")
public class DummyTest {
@Test
public void shouldDoSomething() {
}
}
Lorsque jmsContainer est commentée, le test passe au-dessus. Sinon, je reçois ceci:
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'jmsContainer' defined in class path resource [com/blah/config/jmsContext.xml]:
Cannot resolve reference to bean 'connectionFactory' while setting bean property 'connectionFactory';
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'connectionFactory' defined in class path resource [com/blah/config/jmsContext.xml]:
Invocation of init method failed; nested exception is javax.naming.NameNotFoundException:
Exception in lookup.: `jms/connectionfactory' could not be found.
[Root exception is weblogic.corba.cos.naming.NamingContextAnyPackage.NotFound: IDL:weblogic/corba/cos/naming/NamingContextAny/NotFound:1.0]
Le « connectionFactory » haricot obtient instancié comme une dépendance de « jmsContainer » et il tombe en panne. Avec "jmsContainer" commenté, "connectionFactory" n'est pas instancié. Le code jms fonctionne bien, mais j'ai renommé mes noms JNDI pour que je puisse voir quand les choses ont commencé.
Êtes-vous absolument sûr que ça démarrage? Quelle est la preuve? Pouvez-vous intégrer cette preuve dans votre test? – skaffman
Pour (ma) prospérité future: La création de Bean et le démarrage de conteneurs d'écoute sont des choses différentes. p: autoStartup = "false" empêchera le démarrage du conteneur d'écoute, bien que ses références de beans doivent être résolues. Si vous avez d'autres beans comme JmsMessageDrivenEndpoint qui implémentent SmartLifeCycle, ceux-ci doivent aussi avoir autoStartup = "false", sinon ils démarreront le conteneur d'écoute – Patrick
+1 pour la mention isAutoStartup. C'était mon problème lors de la tentative de chargement de SimpleMessageContextListener pour AMQP. – alph486