1

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

我以这种方式使用 jms 模板设置主题:

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

对于本主题,我以这种方式使用 DefaultMessageListenerContainer 设置 MDB:

<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 的创建时间必须在运行时。

那可能吗?

谢谢,雷。

4

1 回答 1

0

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

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

代码中的ApplicationContext以语法方式实例化 bean。

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

这里是 java doc 中关于这个方法的内容:

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

允许指定显式构造函数参数/工厂方法参数,覆盖 bean 定义中指定的默认参数(如果有)。

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

编辑。

这是一个示例,演示了我在说什么(这很简单,但我没有足够的时间编写更复杂的内容)。

假设有接口和两个它的实现:

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";
    }

}

我们有一个类使用这个接口的具体实现,我们应该动态地向它注入具体实现:

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;
    }
}

这是一个在运行时演示动态注入的测试用例:

@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();
    }

}
于 2012-07-12T08:37:04.973 回答