2010-12-10 2 views
3

JMS 용 스프링 구성을 설정했습니다. 게으른로드 (기본 코드는 lazy-init에주의하십시오.)를 느낄 수 없다는 점만 빼면 잘 작동합니다. 아래 설정에서 jmsContainer (DMLC)를 주석 처리하면 지연로드가 예상대로 작동합니다. 그렇지 않으면 DMLC를 인스턴스화하고 차례로 대기열 및 연결 팩토리를 만듭니다.봄 3.0 지연 초기화가 DefaultMessageListenerContainer에 적합하지 않습니까?

무엇이 누락 되었습니까?

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> 

그리고 내가 운전을 사용하고 테스트, DummyTest.java : jmsContainer이 주석 때

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() { 

    } 

} 

이 테스트는 위의 전달합니다. 그렇지 않으면,이 얻을 :

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] 

은 "ConnectionFactory에"빈은 "jmsContainer"의 종속성으로 인스턴스화됩니다 그것은 실패합니다. "jmsContainer"가 주석 처리 된 상태에서 "connectionFactory"가 인스턴스화되지 않습니다.

jms 코드는 정상적으로 작동하지만 실제로 JNDI 이름의 이름이 변경되어 작업을 시작할 때 알 수 있습니다.

+0

은 시작있어 절대적으로 확신 당신이 있습니까? 증거가 뭐야? 그 증거를 시험에 포함시킬 수 있습니까? – skaffman

+2

(내) 장래 번영을 위해 : 빈 생성과 리스너 컨테이너 시작은 다른 것들입니다. p : autoStartup = "false"를 사용하면 리스너 컨테이너가 시작될 수 없지만 Bean 참조는 해결되어야합니다. SmartLifeCycle을 구현하는 JmsMessageDrivenEndpoint와 같은 다른 bean을 가지고 있다면 autoStartup = "false"가되어야합니다. 그렇지 않으면 isAutoStartup 언급에 대해 청취자 컨테이너 – Patrick

+0

+1을 시작합니다. 이것은 AMQP에 SimpleMessageContextListener를로드하려고 시도 할 때의 내 문제였습니다. – alph486

답변

4

확인이 꽤 불분명하지만, DefaultMessageListenerContainerLifecycle 인터페이스를 구현하고,이를 구현 콩 상황에 맞는 자신의 라이프 사이클에 연결되어 - 컨텍스트가 시작될 때, Lifecycle -implementing 콩을 초기화하고 시작했다. 이것은 당신의 lazy-init 설정이 본질적으로 무시된다는 것을 의미한다.

+1

실제로 SmartLifecycle 인터페이스입니다 : http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/SmartLifecycle.html. Spring은 isAutoStartup을 호출하여 시작해야하는지 여부를 파악할 수 있도록 인스턴스화해야합니다. – cavey79

0

해결책은 autoStartup을 false로 사용하는 것입니다. 아래 코드를 참조하십시오.

<bean id="listenerContainer" 
    class="org.springframework.jms.listener.DefaultMessageListenerContainer"> 
    ........ 
    <property name="autoStartup" value="false"/> 
</bean> 

~ 시암

관련 문제