Spring JMS POJOs - P.1

Sử dụng Spring JMS - phần 1 Khi nhắc tới JMS, tôi đoan chắc rằng bạn đã nghe nói tới nó nhiều như là một Enterprise Java bean, sống trong container đặc tả cho ứng dung EJB, tôi muốn nói tới Message Driven Bean (MDB). JMS được cài đặt trên một EJB container là không khó, và càng trở nên đơn giản hơn trên EJB3 khi được hỗ trợ bởi annotation. Tuy nhiên, luôn có những giải pháp dễ dàng hơn cạnh tranh với những container hạng nặng như EJB từ khi Spring ra đời. Hôm nay tôi giới thiệu Spring JMS làm việc trên những POJO được quản lý bằng IoC container của Spring.

Message Driven POJOs.

Trong những tính năng và cải tiến mới của Spring 2.0, tôi phải nói rằng Message-Driven POJOs rất tuyệt vời.

Sau đây tôi giới thiệu một bài giới thiệu nhanh. Có nhiều cái để nói, và tôi sẽ theo lần lượt để post bài. Bây giờ quan trọng là cung cấp đủ kiến thức để chạy một chương trình JMS bất đồng bộ dựa trên POJOs. Tôi hy vọng bạn sẽ thích thú.

Yêu cầu:

Bạn cần các file JAR sau trong CLASSPATH.

* activemq-core-3.2.2.jar

* concurrent-1.3.4.jar

* geronimo-spec-j2ee-managment-1.0-rc4.jar

* commmons-logging-1.0.4.jar

* log4j-1.2.9.jar

* jms-1.1.jar

* spring-2.0-rc3.jar

Với những ai không thể tìm ra được những file jar này, tôi sẽ gửi cho bạn qua email.

Cài đặt môi trường:

Đầu tiên chúng ta cần cài đặt môi trường. Tôi sẽ sử dụng ActiveMQ, với những bạn chưa nghe hay còn nghe ít về ActiveMQ, xin mời bạn lên trang web activemq.apache.org để tìm hiểu thêm những thông tin về nó, tìm hiểu sức mạnh về nó.

Bài viết này tuy có liên quan nhiều thành phần và nếu như đôi khi có phần nào làm bạn bối rối, xin đừng nản lòng, vì một vài lý do, tôi không thể post toàn bộ project tôi viết lên, nhưng tôi cam đoan sau khi bạn làm từng bước trong bài này, chương trình sẽ chạy thành công. Trường hợp xấu nhất có thể xảy ra là máy bạn báo thiếu bộ nhớ, hay port không thể mở, đó là những vấn đề không phức tạp, tôi luôn sẵn sàng giúp đỡ.

Mọi sự tác động chia sẽ đến chương trình được giới hạn chỉnh sửa tới chỉ một file. Tôi dùng file "shared-context" vì nó khá ngắn và dễ hiểu. Tôi dự định import những bean definitions trên cả 2 bên (client side và server side) của JMS communication.

Sau đây là "shared" bean definitions : một connection factory và 2 hàng đợi (một cho request và một cho reply). Tôi sử dụng file chung này với mục đích khá đơn giản, khi server tiếp nhận dữ liệu trên một port, thì client cũng có thể nhận biết port đó. Đương nhiên, sẽ rất đơn giản nếu bạn tách nó ra, còn ở đây, lý do để chương trình đơn giản nhất., tôi sẽ chọn cách này.

File shared-context.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.xsd">

//Hàng đợi cho request.

<bean id="requestQueue" class="org.activemq.message.ActiveMQQueue">

<constructor-arg value="requestQueue"/>

</bean>

//Hàng đợi cho reply.

<bean id="replyQueue" class="org.activemq.message.ActiveMQQueue">

<constructor-arg value="replyQueue"/>

</bean>

//connection Factory được chạy trên tcp.

//Bạn có thể dùng vm://localhost để thay thế.

<bean id="connectionFactory" class="org.activemq.ActiveMQConnectionFactory">

<property name="brokerURL" value="tcp://localhost:61616"/>

</bean>

</beans>

Đi vào ví dụ:

Tôi sẽ giữ mọi thứ thật đơn giản, mục đích chính là trình bày mọi thứ vừa đủ thôi. Một điều quan trong là phần "domain" là POJOs. Spring và JMS sẽ không phụ thuộc với nhau.

Cuối cùng, chúng ta sẽ chấp nhận một input từ người dùng thông qua stdin và chuyển những thông tin này thành thông tin đăng ký cho một vài sự kiện, input này là client -người sử dụng.

Thông điệp sẽ được gửi bất đồng bộ (request và reply), nghĩa là tôi sẽ sử dụng một queue khác để xử lý việc phản hồi. ReplyNotifier sẽ xác nhận (hay không xác nhận) đến sdtout.

Tôi tạo tất cả những class ở gói "blog.mdb"

Class đầu tiên là RegistrationRequest (Rất đơn giản, nó chứa thông tin request)

package blog.mdp;

import java.io.Serializable;

public class RegistrationRequest implements Serializable {

private static final long serialVersionUID = -6097635701783502292L;

private String name;

public RegistrationRequest(String name) {

this.name = name;

}

public String getName() {

return name;

}

}

Tiếp theo là

(2 Class dưới đây tiếp nhận và đưa ra cách để giải quyết thông điệp - trong ứng dụng thực tế chúng ta sẽ cài đặt bussiness tại class này)

package blog.mdp;

import java.io.Serializable;

public class RegistrationReply implements Serializable {

private static final long serialVersionUID = -2119692510721245260L;

private String name;

private int confirmationId;

public RegistrationReply(String name, int confirmationId) {

this.name = name;

this.confirmationId = confirmationId;

}

public String toString() {

return (confirmationId >= 0)

? name + ": Confirmed #" + confirmationId

: name + ": Not Confirmed";

}

và RegistrationService

package blog.mdp;

import java.util.HashMap;

import java.util.Map;

public class RegistrationService {

private Map registrations = new HashMap();

private int counter = 100;

public RegistrationReply processRequest(RegistrationRequest request) {

int id = counter++;

if (id % 5 == 0) {

id = -1;

}

else {

registrations.put(new Integer(id), request);

}

return new RegistrationReply(request.getName(), id);

}

}

RegistrationService là một the Message-Driven POJO.

Cuối cùng, tạo một class đơn giản để log lại reply messages.

package blog.mdp;

public class ReplyNotifier {

public void notify(RegistrationReply reply) {

System.out.println(reply);

}

}

Phần 2 sẽ là phần thiết lập môi trường để chạy, tôi có post 3 hình bao gồm 3 bước khởi động tôi đã demo tại máy của tôi. Mời bạn tiếp tục theo dõi.

About Langthang

This is a short description in the author block about the author. You edit it by entering text in the "Biographical Info" field in the user admin panel.
    Blogger Comment
    Facebook Comment

0 comments :

Post a Comment