java - 如何以编程方式和动态方式设置 MDB

标签 java spring jms message-driven-bean

我在独立环境中使用 Spring3.1。

我用 jms 模板设置主题是这样的:

<bean id="mm1sessionsTopicSendingTemplate" class="org.springframework.jndi.JndiObjectFactoryBean"
    depends-on="jmsServerManagerImpl">
    <property name="jndiName">
        <value>/topic/mm1sessionsTopic</value>
    </property>
</bean>

对于本主题,我通过以下方式设置 MDB 和 DefaultMessageListenerContainer:

<bean id="mm1sessionDispatcherListener"
        class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="pubSubDomain" value="true" />
        <property name="concurrentConsumers" value="1" />
        <property name="destination" ref="mm1sessionsTopicSendingTemplate" />
        <property name="messageListener" ref="mm1SessionMDB" />
        <property name="sessionAcknowledgeModeName" value="AUTO_ACKNOWLEDGE" />
    </bean>

这样我必须通过xml提前设置mm1SessionMDB:

<bean id="mm1SessionMDB" class="com.mdb.SessionMDB">
        <property name="feedPropertiesDTO" ref="feedListenerMarketMaker1Properties" />

    </bean>

但我需要我的应用程序以编程方式创建 MDB 实例。

我的意思是我想通过代码创建 mdb,因为每个 MDB 对于从主题检索的消息都有不同的验证值(通过 feedPropertiesDTO)

基本上,我将拥有具有相同逻辑的 MDB 池,但每个 MDB 都有不同的属性。 MDB 的创建时间必须在运行时。

这可能吗?

谢谢, 射线。

最佳答案

我认为你可以使用工厂方法来实例化你的MDB bean并使用方法

Object getBean(String name, Object... args) throws BeansException;

代码中的ApplicationContext,用于以编程方式实例化 bean。

据我所知,此方法允许您将参数路径传递给工厂方法。

Java 文档中对此方法的描述如下:

返回指定 bean 的实例,该实例可以是共享的,也可以是独立的。

Allows for specifying explicit constructor arguments / factory method arguments, overriding the specified default arguments (if any) in the bean definition.

我从未使用过这种方法,但我认为它适合您的情况。

编辑。

这是一个示例,演示了我正在谈论的内容(非常简单,但我没有足够的时间来编写更复杂的内容)。

假设有一个接口(interface)和两个它的实现:

public interface StringMakerInterface {

    // Just return simple String depending on concrete implementation.
    String returnDummyString();

}

public class StringMakerImpl1 implements StringMakerInterface {

    public String returnDummyString() {
        return "test bean impl 1";
    }


}

public class StringMakerImpl2 implements StringMakerInterface{

    public String returnDummyString() {
        return "test bean impl 2";
    }

}

我们有一个类使用该接口(interface)的具体实现,并且我们应该动态地向其注入(inject)具体实现:

public class StringPrinter {

    private StringMakerInterface stringMaker;

    public StringMakerInterface getStringMaker() {
        return stringMaker;
    }

    public void setStringMaker(StringMakerInterface stringMaker) {
        this.stringMaker = stringMaker;
    }

    public StringPrinter() {

    }

    // Just print dummy string, returned by implementation
    public void printString() {
        System.out.println(stringMaker.returnDummyString());
    }
}

这是我的示例的配置类:

@Configuration
public class TestFactoryMethodConfig {

    @Bean(name = "stringMaker1")
    public StringMakerImpl1 stringMaker1() {
        return new StringMakerImpl1();
    }

    @Bean(name = "stringMaker2")
    public StringMakerImpl2 stringMaker2() {
        return new StringMakerImpl2();
    }

    @Bean(name = "stringPrinter")
    @Scope(value = "prototype")
    public StringPrinter stringPrinter(@Qualifier("stringMaker1") StringMakerInterface stringMaker) {
        StringPrinter instance = new StringPrinter();
        instance.setStringMaker(stringMaker);

        return instance;
    }
}

这是一个测试用例,演示了运行时的动态注入(inject):

@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={TestFactoryMethodConfig.class})
public class TestFactoryMethod {

    @Autowired
    private ApplicationContext applicationContext;

    @Resource(name = "stringMaker1")
    private StringMakerInterface stringMaker1;

    @Resource(name = "stringMaker2")
    private StringMakerInterface stringMaker2;

    @Test
    public void testFactoryMethodUsage() {

        StringPrinter stringPrinter1 = (StringPrinter) applicationContext.getBean("stringPrinter", stringMaker1);

        StringPrinter stringPrinter2 = (StringPrinter) applicationContext.getBean("stringPrinter", stringMaker2);

        stringPrinter1.printString();
        stringPrinter2.printString();
    }

}

关于java - 如何以编程方式和动态方式设置 MDB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11446978/

相关文章:

java - 在 JAVA 中删除字符串中的重复项。不允许使用额外的数据结构

java - 在 session bean 中存储进度信息

java - 如何从来自 MQ 的消息中检索 RFH 消息头?

java - ActiveMQ 故障转移 : How to detect when an application starts and cannot find a broker

java - IBM MQ : Any way to get connection interruption notification?

java - Tapestry 5 - 两个组件之间的通信

java - 有没有办法用空格分隔文件扫描仪,但将名字和姓氏用空格分隔为一个字符串?

java - Gradle 项目错误 - java.lang.ClassNotFoundException : org. springframework.boot.SpringApplication

Java 集合。添加(E obj),但删除(Object obj)

java - Spring MVC : Saving a string in servlet-context and accessing from java code