Spring是一個完整的J2EE框架和解決方案,完整並且模塊化,你可以用的他的全部也可以只用他的一部分特性,Spring 包含 IoC, AOP, 事務處理,ORM, 也包括一個簡單的MVC框架.
用Spring,自我感覺,可以使你的代碼至少節約30%,它的很多template很不錯的,比如簡單封裝後的jdbctemplate,jmstemplate等。
ioc用後就會愛不釋手,它讓你的代碼風格完全改觀。以前我要產生個對象,絕大多數時候只回想到new一個對象,而用spring的ioc,beanfactory,只需要配置一個xml文件即可。這種方式實現了松偶合,對單元測試非常有利。
還有它的aop,也是很不錯的,
用spring的感覺,正如它的名字一樣:如沐春風.
關於spring中的jms,最近一個項目用到,剛好研究了一下,在這裏做一個整理備份.在此感謝同事Eric的幫助.
spring把jms進行了簡單的封裝,用它的JmsTemplate可以很方便的發送和接收消息,並且資源的管理都由template來管理了.
1:在web.xml文件中配置一個spring用的上下文:
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/jmsconfig.xml
</param-value>
</context-param>
jmsconfig.xml用來裝配jms,內容如下:
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="jmsConnectionFactory"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>jms/Ntelagent/RequestQCF</value>
</property>
</bean>
<bean id="destination"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>jms/Ntelagent/RequestQ</value>
</property>
</bean>
<bean id="jmsConnectionFactoryForReceive"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>jms/Ntelagent/ResponseQCF</value>
</property>
</bean>
<bean id="destinationForReceive"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>jms/Ntelagent/ResponseQ</value>
</property>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate102">
<property name="connectionFactory">
<ref bean="jmsConnectionFactory"/>
</property>
<property name="defaultDestination">
<ref bean="destination"/>
</property>
<property name="messageConverter">
<ref bean="jmsTrxConverter"/>
</property>
<property name="receiveTimeout">
<value>1</value>
</property>
</bean>
<bean id="jmsTemplateForReceive" class="org.springframework.jms.core.JmsTemplate102">
<property name="connectionFactory">
<ref bean="jmsConnectionFactoryForReceive"/>
</property>
<property name="defaultDestination">
<ref bean="destinationForReceive"/>
</property>
<property name="messageConverter">
<ref bean="jmsTrxConverter"/>
</property>
<property name="receiveTimeout">
<value>1</value>
</property>
</bean>
<bean id="jmsTrxConverter" class="co.transport.jms.JmsTransactionConverter">
<property name="rspQueue">
<ref bean="destinationForReceive"/>
</property>
</bean>
<bean id="jmsRequestTransport" class="co.transport.jms.JmsRequestTransport">
<property name="jmsTemplate">
<ref bean="jmsTemplate"/>
</property>
<property name="jmsTemplateForReceive">
<ref bean="jmsTemplateForReceive"/>
</property>
</bean>
</beans>
其中:
jmsConnectionFactory爲jms連接工廠,屬性jndiName的value爲server服務配置的jndi名稱.
destination爲消息隊列,屬性jndiName爲消息隊列的jndi名稱.
jmsTemplate爲配置spring消息模版:採用JmsTemplate102(如果你的JMS實現符合JMS規範1.1版,則應該使用JmsTemplate),其中的messageConverter屬性配置了一個消息轉換器,因爲通常消息在發送前和接收後都需要進行一個前置和後置處理,轉換器便進行這個工作。
由於我的sendQueue很receiveRueue是不同的queue,所以我配置了兩個jmsTemplate:
jmsTemplateForReceive負責接收消息,jmsTemplate負責發發送消息.
發送消息的代碼很簡單:
jmsTemplate.convertAndSend(request);
接收消息也很簡單:
Object obj = jmsTemplate.receiveAndConvert();
如果需要用一個過濾器接收特定的消息,則:
Object obj = this.jmsTemplateForReceive.receiveSelectedAndConvert(this.messageSelector);
發送和接收消息的class如下:
public class JmsRequestTransport implements RequestTransport {
private JmsTemplate jmsTemplate;
private JmsTemplate jmsTemplateForReceive;
private String messageSelector;
private String destinationName;
public void setJmsTemplate(JmsTemplate template){
this.jmsTemplate = template;
}
public void request(Object request) {
jmsTemplate.convertAndSend(request);
}
public Object receive() {
System.out.println("in JmsRequestTransport: destinationName = " + this.jmsTemplateForReceive.getDefaultDestinationName());
System.out.println("in JmsRequestTransport: messageSelector = " + messageSelector);
Object obj = this.jmsTemplateForReceive.receiveSelectedAndConvert(this.messageSelector);
return obj;
}
public String getMessageSelector() {
return messageSelector;
}
public void setMessageSelector(String string) {
messageSelector = string;
}
public String getDestinationName() {
return destinationName;
}
public void setDestinationName(String string) {
destinationName = string;
}
public JmsTemplate getJmsTemplateForReceive() {
return jmsTemplateForReceive;
}
public void setJmsTemplateForReceive(JmsTemplate template) {
jmsTemplateForReceive = template;
}
}
要實現一個消息轉換器,只需要實現MessageConverter接口,MessageConverter很簡單,它只有兩個方法需要實現:
public Object fromMessage(Message msg){}
public Message toMessage(Object obj, Session session) throws JMSException{}
fromMessage爲接收消息後,對消息進行的轉換(通常是把一個message轉化爲一個Object對象)
toMessage爲發送消息前需要的轉化(通常爲把一個Object轉化爲一個message對象)
我的JmsTransactionConverter轉換器如下:
private Queue rspQueue;
public JmsTransactionConverter(){}
public Object fromMessage(Message msg){
MessageBean msgBean = new MessageBean();
TextMessage massage = (TextMessage)msg;
try {
String str = massage.getText();
msgBean.setHead("HeadTest");
msgBean.setOutput(str);
msgBean.setStatus("success");
} catch (JMSException e) {
// TODO Auto-generated catch block
msgBean = null;
e.printStackTrace();
}
finally {
return msgBean;
}
}
public Message toMessage(Object obj, Session session) throws JMSException{
String s = (String)obj;
TextMessage message = session.createTextMessage(s);
message.setStringProperty("mytype","java");
return message;
}
public Queue getRspQueue() {
return rspQueue;
}
public void setRspQueue(Queue queue) {
rspQueue = queue;
}
}
其中:MessageBean是一個簡單javabean:
private String head;
private String output;
private String status;
public String getHead() {
return head;
}
public String getOutput() {
return output;
}
public String getStatus() {
return status;
}
public void setHead(String string) {
head = string;
}
public void setOutput(String string) {
output = string;
}
public void setStatus(String string) {
status = string;
}
}
然後就可以用兩個servlet來測試發送和接收消息:
發送消息:
/**
* @see javax.servlet.http.HttpServlet#void (javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
doGet(req, resp);
}
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException{
ServletOutputStream out = resp.getOutputStream();
try {
ServletContext servletContext = this.getServletContext();
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
JmsRequestTransport transport = (JmsRequestTransport)wac.getBean("jmsRequestTransport");
System.out.println("in JMSTestServlet.doGet:begin send message");
String messageToSend = req.getParameter("message");
if(messageToSend == null)
{
messageToSend = "Default Message";
}
transport.request(messageToSend);
String s = "in JMSTestServlet.doGet:after send message and message is: " + messageToSend;
out.println("<HTML><BODY>");
out.println(s);
out.println("<br><input type=button name=back value=back οnclick=history.back()>");
out.println("<br><a href=receiveServlet>receive</a>");
out.println("</HTML></BODY>");
} catch(Exception e) {
out.println("<HTML><BODY>");
out.println(e.toString());
out.println("</HTML></BODY>");
}
}
接收消息:
/**
* @see javax.servlet.http.HttpServlet#void (javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
doGet(req, resp);
}
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
ServletOutputStream out = resp.getOutputStream();
String selector = req.getParameter("selector");
String distination = req.getParameter("distination");
try {
String s = "nothing";
ServletContext servletContext = this.getServletContext();
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
JmsRequestTransport transport = (JmsRequestTransport)wac.getBean("jmsRequestTransport");
System.out.println("selector = " + selector);
System.out.println("distination = " + distination);
transport.setDestinationName(distination);
transport.setMessageSelector(selector);
Object obj = transport.receive();
if(obj != null) {
MessageBean msgBean = (MessageBean)obj;
//System.out.println("in receiveServlet:");
s = "receive the message is: " + msgBean.getHead() + "," +
msgBean.getOutput() + ", " +
msgBean.getStatus();
} else {
s = "there is no message where " + selector;
}
out.println("<HTML><BODY>");
out.println(s);
out.println("<br>selector is :" + selector);
out.println("<br>distination is :" + distination);
out.println("<br><a href=jsp/sendMessage.jsp>sendMessage</a>");
out.println("</HTML></BODY>");
} catch(Exception e) {
out.println("<HTML><BODY>");
out.println("<br>selector is :" + selector);
out.println("<br>distination is :" + distination);
out.println("<br>" + e.toString());
out.println("</HTML></BODY>");
}
}
}