Monday, August 22, 2005

Message Driver Bean with Spring

ActiveMQ เป็น Opensource JMS provider ตัวหนึ่งทีี่มีคนนิยมใช้
เช่น Geronimo ก็เอาไป integrate เป็น Message Service ของตัวเอง

ใน ActiveMQ มี sub project ตัวหนึ่งที่ชื่อ Jencks
ทำหน้าที่เป็น lightweight JCA container
สามารถ config เข้าไปใน Spring Framework เพื่อที่จะให้บริการ Message Driver Bean ได้
(โดยไม่ต้องมี J2ee Application Server)

Message Bean


ทดลองเขียน Message Bean ง่ายๆ
package mx.test.mq;

import java.util.Enumeration;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

public class EchoBean implements MessageListener {

public void onMessage(Message msg) {
try {
TextMessage txt = (TextMessage) msg;
System.out.println(txt.getText());
} catch (JMSException je) {
je.printStackTrace();
}
}
}

จากนั้นก็ add Container เข้าไปใน Spring
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org
/dtd/spring-beans.dtd">
<beans>
<bean id="jencks" class="org.jencks.JCAContainer">
<property name="bootstrapContext">
<bean class="org.jencks.factory.BootstrapContextFactoryBean">
<property name="threadPoolSize" value="25"/>
</bean>
</property>

<property name="resourceAdapter">
<bean id="activeMQResourceAdapter" class="org.activemq.ra.ActiveMQRe
sourceAdapter">
<property name="serverUrl" value="tcp://localhost:61616"/>
</bean>
</property>
</bean>

<bean id="monitor" factory-method="addConnector" factory-bean="jencks" singl
eton="true">
<property name="activationSpec">
<bean class="org.activemq.ra.ActiveMQActivationSpec">
<property name="destination" value="Monitor.Queue"/>
<property name="destinationType" value="javax.jms.Queue"/>
</bean>
</property>

<property name="ref" value="echoBean"/>
</bean>

<bean id="echoBean" class="mx.test.mq.EchoBean" singleton="true"/>

</beans>

จากนั้นก็ทดลองเขียน Java Class ที่ใช้ในการ start service
package mx.test.mq;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

/**
* @param args
*/
public static void main(String[] args) {
ClassPathXmlApplicationContext appContext =
new ClassPathXmlApplicationContext(
new String[] {"beans.xml"});
}

}


ทดลองเขียน Client เพื่อส่ง Message


เราจะใช้ Spring JmsTemplate เข้ามาช่วย
โดยเขียน Spring Config file ดังนี้
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org
/dtd/spring-beans.dtd">
<beans>
<bean id="jmsFactory" class="org.activemq.ActiveMQConnectionFactory">
<property name="brokerURL">
<value>tcp://localhost:61616</value>
</property>

</bean>

<!-- Spring JMS Template -->
<bean id="jms" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref local="jmsFactory"/>
</property>
<property name="defaultDestinationName" value="Monitor.Queue"/>
</bean>
</beans>

ทดลองส่ง Message ดังนี้
package mx.test.mq;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

public class Client {

/**
* @param args
*/
public static void main(String[] args) {
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationC
ontext(
new String[] { "client.xml" });
JmsTemplate jms = (JmsTemplate) appContext.getBean("jms");
jms.send(new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("hello queue world");
}
});
}

}


Note: ก่อนจะ run อย่าลืม start ActiveMq ให้เรียบร้อยก่อน

เท่าที่ทดสอบดู ก็ work ok ดี แต่ไม่ค่อยชอบอยู่จุดหนึ่ง ตรง dependency file
ที่ต้องใช้ ลองดูว่าต้องใช้อะไรบ้าง
* connector-api.jar -> JCA api
* geronimo-transaction.jar
* geronimo-connector.jar
* geronimo-kernel.jar
* geronimo-j2ee.jar
* jencks.jar
* activemq-ra.jar
* activemq-core.jar
* geronimo-spec-jms.jar -> JMS api
* geronimo-spec-j2ee-management.jar (javax.management.j2ee)
* concurrent-1.3.4.jar
* commons-logging.jar
กลุ่มล่างๆไม่ติดใจอะไร เพราะเป็น Spec Api ที่ต้อง import อยู่แล้ว
แต่กลุ่มบน จะเห็นว่า dependency กับ Geronimo เยอะมาก

ที่สนใจ JMS ตอนนี้ก็เพราะว่า สามารถเอามาใช้เป็น infrastructure ใน
การ integrate rails, java เข้าหากันได้ (ผ่านทาง TTMP protocol ของ ActiveMQ)
โดยให้ rails เป็นส่วน Web Application และใช้ Java เป็น Business Tier

Related link from Roti

No comments: