복붙노트

[SPRING] DefaultMessageListenerContainer에 대해 봄 3.0 지연 초기화가 적용되지 않습니까?

SPRING

DefaultMessageListenerContainer에 대해 봄 3.0 지연 초기화가 적용되지 않습니까?

JMS 용 스프링 구성을 설정했습니다. 게으른로드 (less-load)를 얻을 수 없다는 점을 제외하고는 정상적으로 작동합니다 (아래 코드에서 default-lazy-init에 주목하십시오). 아래 설정에서 jmsContainer (DMLC)를 주석 처리하면 지연로드가 예상대로 작동합니다. 그렇지 않으면 DMLC를 인스턴스화하고 차례로 대기열 및 연결 팩토리를 만듭니다.

내가 뭘 놓치고 있니?

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 :

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

    }

}

jmsContainer가 주석 처리되면 위의 테스트가 통과됩니다. 그렇지 않으면, 나는 이것을 얻는다.

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"bean은 "jmsContainer"의 종속성으로 인스턴스화되고 실패합니다. "jmsContainer"가 주석 처리 된 상태에서 "connectionFactory"가 인스턴스화되지 않습니다.

jms 코드는 정상적으로 작동하지만, JNDI 이름의 이름이 의도적으로 변경되었으므로 언제 시작되는지 확인할 수 있습니다.

해결법

  1. ==============================

    1.OK, 이것은 매우 모호 합니다만, DefaultMessageListenerContainer는 Lifecycle 인터페이스를 구현하고 이것을 구현하는 빈은 컨텍스트 자체의 라이프 사이클에 연결됩니다. 컨텍스트가 시작되면 Lifecycle- 빈을 초기화하는 것이 초기화되고 시작됩니다. 이것은 당신의 lazy-init 설정이 본질적으로 무시된다는 것을 의미한다.

    OK, 이것은 매우 모호 합니다만, DefaultMessageListenerContainer는 Lifecycle 인터페이스를 구현하고 이것을 구현하는 빈은 컨텍스트 자체의 라이프 사이클에 연결됩니다. 컨텍스트가 시작되면 Lifecycle- 빈을 초기화하는 것이 초기화되고 시작됩니다. 이것은 당신의 lazy-init 설정이 본질적으로 무시된다는 것을 의미한다.

  2. ==============================

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

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

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

    ~ Shyam

  3. from https://stackoverflow.com/questions/4412628/spring-3-0-lazy-init-not-honoured-for-defaultmessagelistenercontainer by cc-by-sa and MIT license