Преобразование MDL WebLogic в POJO, управляемые сообщениями Spring

У меня есть приложение, построенное на WebLogic 11b (10.3.4) с использованием MDB. Я пытаюсь преобразовать их в Spring MDP. Вот вопрос MDB:

@MessageDriven(activationConfig = {
        @ActivationConfigProperty(propertyName = "ejbName", propertyValue = "RecipientEventRouterBean"),
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
        @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
        @ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "Durable") })
public class RecipientEventRouterBean extends TraxMessageRouter {

    @Resource
    private int appInstance;

    @Resource
    private String appName;

    @Resource(mappedName = "jms/TraxErrorQ")
    private Queue errorQueue;

    @Resource(name = "TraxCF")
    private ConnectionFactory errorQueueConnectionFactory;

    @EJB
    private Logger loggingService;

    @Resource
    private int maxJMSXDeliveryCount;

    @Resource
    private boolean validate;

    @EJB
    protected RecipientRegistrationService recService;

    @Override
    @PostConstruct
    public void init() {

        if (appName == null) {
            throw new EJBException("appName is null");
        }

        try {
            super.traxFactory = TraxFactory.getInstance(Application.fromValue(appName));
            super.processor = new ObjectFactory().createApplicationInstance();
            super.processor.setName(appName);
            super.processor.setInstance(this.appInstance);
            super.errorQueueConnectionFactory = this.errorQueueConnectionFactory;
            super.errorQueue = this.errorQueue;
            super.maxJMSXDeliveryCount = this.maxJMSXDeliveryCount;
            super.validate = this.validate;
            super.loggingService = this.loggingService;
        } catch (Exception e) {
            throw new EJBException(e);
        }

        super.init();
    }

    @Override
    protected TraxMessageService getTraxMessageService() {

        return recService;
    }

}

Родитель MDB, TraxMessageRouter, реализует интерфейс MessageListener.

Я создал бобы MDP в jms-applicationContext.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <!-- Spring JMS Destination Resolver -->
    <bean id="jmsDestinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver">
        <property name="cache" value="true" />
    </bean>


    <!-- Spring JMS Queue Connection Factory leveraging a single connection -->
    <!-- SingleConnectionFactory will return the same Connection on all createConnection calls and ignore calls to close -->
    <bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="jms/TraxCF" />
    </bean>

    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="destinationResolver" ref="jmsDestinationResolver" />
    </bean>

    <bean id="jmsSender" class="com.mycompany.web.service.jms.JMSSender">
        <property name="jmsTemplate" ref="jmsTemplate" />
    </bean>

    <bean id="jmsReceiver" class="com.mycompany.web.service.jms.JMSReceiver">
        <property name="jmsTemplate" ref="jmsTemplate" />
    </bean> 

    <bean id="jmsQueue" class="javax.jms.Topic" />  

    <!-- this is the Message Driven POJO (MDP) -->
    <bean id="messageListener" class="com.mycompany.messaging.RecipientEventRouterBean" />

    <!-- and this is the message listener container -->
    <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory"/>
        <property name="destination" ref="jmsQueue"/>
        <property name="messageListener" ref="messageListener" />
    </bean>
</beans>

Как преобразовать аннотацию @MessageDriven в правильный синтаксис Spring? Могу ли я просто закомментировать это сейчас?

У меня есть еще несколько EventRouterBeans. Все ли они получают объявления bean-компонентов в jms-ApplicationContext.xml или я могу добавить родительский элемент TraxMessageRouter в xml?

Какие еще изменения необходимо внести в файлы конфигурации? Есть ли хорошее руководство о том, как перейти от MDB к MDP? Есть ли хорошее руководство о том, как перейти с EJB 3 на Spring?

1 ответ

Решение

Это выглядит почти нормально для меня. Вот несколько советов:

  • Да, вы можете удалить @MessageDriven аннотация, так как вы уже настроили контейнер
  • Ваш боб jmsQueueнеправильно. Поскольку вы используете weblogic, вы должны либо найти очередь, используя JNDI (как вы это делали для фабрики соединений), либо вы должны указать (jndi) имя очереди, используя destinationName свойство (которое принимает String и не javax.jms.Destination)

Вам нужно одно объявление для каждого прослушивателя сообщений, которое вы хотите развернуть. Возможно, вы должны пойти по пути пространства имен xml, чтобы поделиться этими настройками?

<jms:listener-container connectionFactory="connectionFactory" 
                        destinationResolver="jmsDestinationResolver">
    <jms:listener ... />
    <jms:listener ... />
</jms:listener-container>

Это создаст два контейнера слушателя (т.е. один контейнер на jms:listener запись).

Также обратите внимание, что Spring 4.1 предоставит лучший декларативный подход, в котором вы можете просто аннотировать метод любого управляемого bean-компонента Spring. Проверьте этот блог для получения дополнительной информации. 4.1.0.RC2 был выпущен, так что вы можете попробовать это сейчас.

Другие вопросы по тегам