最近学习Spring对mdb(消息驱动Bean)的支持,折腾了两个星期,总算搞定了。现将配置总结如下:
一.ejb部分。
mdb类:
package
com.mdb.ejb;
import javax.ejb.EJBException;
import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
/** */ /**
* XDoclet-based Message Driven entity bean.
*
* To generate EJB related classes using XDoclet: - Add Standard EJB module to
* XDoclet project properties - Customize XDoclet configuration - Run XDoclet
*
* Below are the xdoclet-related tags needed for this EJB.
*
* @ejb.bean name="Hello" display-name="Name for Hello" description="Description
* for Hello" destination-type="javax.jms.Queue"
* acknowledge-mode="Auto-acknowledge"
* @weblogic.pool max-beans-in-free-pool="10" initial-beans-in-free-pool="2"
* @weblogic.message-driven destination-jndi-name="ejb/Hello"
* initial-context-factory="weblogic.jndi.WLInitialContextFactory"
* connection-factory-jndi-name="helloConnectionFactory"
*/
public class HelloBean implements MessageDrivenBean, MessageListener ... {
private static final long serialVersionUID = 1L;
/** *//** The MessageDrivenContext */
MessageDrivenContext context;
public HelloBean() ...{
super();
// TODO Auto-generated constructor stub
}
/** *//**
* Set the associated context. The container calls this method after the
* instance creation. <br>
*
* The enterprise bean instance should store the reference to the context
* object in an instance variable. <br>
*
* This method is called with no transaction context.
*
* @param newContext
* A MessageDrivenContext interface for the instance.
*
* @throws EJBException
* Thrown by the method to indicate a failure caused by a
* system-level error.
*/
public void setMessageDrivenContext(MessageDrivenContext newContext)
throws EJBException ...{
context = newContext;
}
public void ejbRemove() throws EJBException ...{
// TODO Auto-generated method stub
}
public void onMessage(Message recvMsg) ...{
System.out.println("HelloBean接收到的消息:");
try ...{
TextMessage message = (TextMessage) recvMsg;
System.out.println(message.getText());
} catch (JMSException e) ...{
e.printStackTrace();
}
}
/** *//**
* An ejbCreate method as required by the EJB specification.
*
* The container calls the instance?s <code>ejbCreate</code> method
* immediately after instantiation.
*
* @ejb.create-method
*/
public void ejbCreate() ...{
}
}
import javax.ejb.EJBException;
import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
/** */ /**
* XDoclet-based Message Driven entity bean.
*
* To generate EJB related classes using XDoclet: - Add Standard EJB module to
* XDoclet project properties - Customize XDoclet configuration - Run XDoclet
*
* Below are the xdoclet-related tags needed for this EJB.
*
* @ejb.bean name="Hello" display-name="Name for Hello" description="Description
* for Hello" destination-type="javax.jms.Queue"
* acknowledge-mode="Auto-acknowledge"
* @weblogic.pool max-beans-in-free-pool="10" initial-beans-in-free-pool="2"
* @weblogic.message-driven destination-jndi-name="ejb/Hello"
* initial-context-factory="weblogic.jndi.WLInitialContextFactory"
* connection-factory-jndi-name="helloConnectionFactory"
*/
public class HelloBean implements MessageDrivenBean, MessageListener ... {
private static final long serialVersionUID = 1L;
/** *//** The MessageDrivenContext */
MessageDrivenContext context;
public HelloBean() ...{
super();
// TODO Auto-generated constructor stub
}
/** *//**
* Set the associated context. The container calls this method after the
* instance creation. <br>
*
* The enterprise bean instance should store the reference to the context
* object in an instance variable. <br>
*
* This method is called with no transaction context.
*
* @param newContext
* A MessageDrivenContext interface for the instance.
*
* @throws EJBException
* Thrown by the method to indicate a failure caused by a
* system-level error.
*/
public void setMessageDrivenContext(MessageDrivenContext newContext)
throws EJBException ...{
context = newContext;
}
public void ejbRemove() throws EJBException ...{
// TODO Auto-generated method stub
}
public void onMessage(Message recvMsg) ...{
System.out.println("HelloBean接收到的消息:");
try ...{
TextMessage message = (TextMessage) recvMsg;
System.out.println(message.getText());
} catch (JMSException e) ...{
e.printStackTrace();
}
}
/** *//**
* An ejbCreate method as required by the EJB specification.
*
* The container calls the instance?s <code>ejbCreate</code> method
* immediately after instantiation.
*
* @ejb.create-method
*/
public void ejbCreate() ...{
}
}
ejb-jar.xml:
<?
xml version="1.0" encoding="UTF-8"
?>
<! DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd" >
< ejb-jar >
< description > <![CDATA[ No Description. ]]> </ description >
< display-name > Generated by XDoclet </ display-name >
< enterprise-beans >
<!--
To add session beans that you have deployment descriptor info for, add
a file to your XDoclet merge directory called session-beans.xml that contains
the <session></session> markup for those beans.
-->
<!-- Entity Beans -->
<!--
To add entity beans that you have deployment descriptor info for, add
a file to your XDoclet merge directory called entity-beans.xml that contains
the <entity></entity> markup for those beans.
-->
<!-- Message Driven Beans -->
< message-driven >
< description > <![CDATA[ Description for Hello ]]> </ description >
< display-name > Name for Hello </ display-name >
< ejb-name > Hello </ ejb-name >
< ejb-class > com.mdb.ejb.HelloBean </ ejb-class >
< transaction-type > Container </ transaction-type >
< acknowledge-mode > Auto-acknowledge </ acknowledge-mode >
< message-driven-destination >
< destination-type > javax.jms.Queue </ destination-type >
</ message-driven-destination >
</ message-driven >
<!--
To add message driven beans that you have deployment descriptor info for, add
a file to your XDoclet merge directory called message-driven-beans.xml that contains
the <message-driven></message-driven> markup for those beans.
-->
</ enterprise-beans >
<!-- Relationships -->
<!-- Assembly Descriptor -->
<!--
To specify your own assembly descriptor info here, add a file to your
XDoclet merge directory called assembly-descriptor.xml that contains
the <assembly-descriptor></assembly-descriptor> markup.
-->
< assembly-descriptor >
<!--
To specify additional security-role elements, add a file in the merge
directory called ejb-security-roles.xml that contains them.
-->
<!-- method permissions -->
<!--
To specify additional method-permission elements, add a file in the merge
directory called ejb-method-permissions.ent that contains them.
-->
<!-- transactions -->
<!--
To specify additional container-transaction elements, add a file in the merge
directory called ejb-container-transactions.ent that contains them.
-->
<!-- finder transactions -->
<!-- message destinations -->
<!--
To specify additional message-destination elements, add a file in the merge
directory called ejb-message-destinations.ent that contains them.
-->
<!-- exclude list -->
<!--
To specify an exclude-list element, add a file in the merge directory
called ejb-exclude-list.xml that contains it.
-->
</ assembly-descriptor >
</ ejb-jar >
<! DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd" >
< ejb-jar >
< description > <![CDATA[ No Description. ]]> </ description >
< display-name > Generated by XDoclet </ display-name >
< enterprise-beans >
<!--
To add session beans that you have deployment descriptor info for, add
a file to your XDoclet merge directory called session-beans.xml that contains
the <session></session> markup for those beans.
-->
<!-- Entity Beans -->
<!--
To add entity beans that you have deployment descriptor info for, add
a file to your XDoclet merge directory called entity-beans.xml that contains
the <entity></entity> markup for those beans.
-->
<!-- Message Driven Beans -->
< message-driven >
< description > <![CDATA[ Description for Hello ]]> </ description >
< display-name > Name for Hello </ display-name >
< ejb-name > Hello </ ejb-name >
< ejb-class > com.mdb.ejb.HelloBean </ ejb-class >
< transaction-type > Container </ transaction-type >
< acknowledge-mode > Auto-acknowledge </ acknowledge-mode >
< message-driven-destination >
< destination-type > javax.jms.Queue </ destination-type >
</ message-driven-destination >
</ message-driven >
<!--
To add message driven beans that you have deployment descriptor info for, add
a file to your XDoclet merge directory called message-driven-beans.xml that contains
the <message-driven></message-driven> markup for those beans.
-->
</ enterprise-beans >
<!-- Relationships -->
<!-- Assembly Descriptor -->
<!--
To specify your own assembly descriptor info here, add a file to your
XDoclet merge directory called assembly-descriptor.xml that contains
the <assembly-descriptor></assembly-descriptor> markup.
-->
< assembly-descriptor >
<!--
To specify additional security-role elements, add a file in the merge
directory called ejb-security-roles.xml that contains them.
-->
<!-- method permissions -->
<!--
To specify additional method-permission elements, add a file in the merge
directory called ejb-method-permissions.ent that contains them.
-->
<!-- transactions -->
<!--
To specify additional container-transaction elements, add a file in the merge
directory called ejb-container-transactions.ent that contains them.
-->
<!-- finder transactions -->
<!-- message destinations -->
<!--
To specify additional message-destination elements, add a file in the merge
directory called ejb-message-destinations.ent that contains them.
-->
<!-- exclude list -->
<!--
To specify an exclude-list element, add a file in the merge directory
called ejb-exclude-list.xml that contains it.
-->
</ assembly-descriptor >
</ ejb-jar >
weblogic-ejb-jar.xml:
<?
xml version="1.0" encoding="UTF-8"
?>
<! DOCTYPE weblogic-ejb-jar PUBLIC "-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN" "http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd" >
< weblogic-ejb-jar >
< description > <![CDATA[ Generated by XDoclet ]]> </ description >
< weblogic-enterprise-bean >
< ejb-name > Hello </ ejb-name >
< message-driven-descriptor >
< pool >
< max-beans-in-free-pool > 10 </ max-beans-in-free-pool >
< initial-beans-in-free-pool > 2 </ initial-beans-in-free-pool >
</ pool >
< destination-jndi-name > ejb/Hello </ destination-jndi-name >
< initial-context-factory > weblogic.jndi.WLInitialContextFactory </ initial-context-factory >
< connection-factory-jndi-name > helloConnectionFactory </ connection-factory-jndi-name >
</ message-driven-descriptor >
< reference-descriptor >
</ reference-descriptor >
</ weblogic-enterprise-bean >
<!--
To add enterprise beans that you have deployment descriptor info for, add
a file to your XDoclet merge directory called weblogic-enterprise-beans.xml that contains
the <weblogic-enterprise-bean></weblogic-enterprise-bean> markup for those beans.
-->
<!--
To add a security-role-assignment section, add
a file to your XDoclet merge directory called weblogic-security-role-assignment.xml that contains
the <security-role-assignment></security-role-assignment> markup.
-->
<!--
To add a run-as-role-assignment section, add
a file to your XDoclet merge directory called weblogic-run-as-role-assignment.xml that contains
the <run-as-role-assignment></run-as-role-assignment> markup.
-->
</ weblogic-ejb-jar >
<! DOCTYPE weblogic-ejb-jar PUBLIC "-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN" "http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd" >
< weblogic-ejb-jar >
< description > <![CDATA[ Generated by XDoclet ]]> </ description >
< weblogic-enterprise-bean >
< ejb-name > Hello </ ejb-name >
< message-driven-descriptor >
< pool >
< max-beans-in-free-pool > 10 </ max-beans-in-free-pool >
< initial-beans-in-free-pool > 2 </ initial-beans-in-free-pool >
</ pool >
< destination-jndi-name > ejb/Hello </ destination-jndi-name >
< initial-context-factory > weblogic.jndi.WLInitialContextFactory </ initial-context-factory >
< connection-factory-jndi-name > helloConnectionFactory </ connection-factory-jndi-name >
</ message-driven-descriptor >
< reference-descriptor >
</ reference-descriptor >
</ weblogic-enterprise-bean >
<!--
To add enterprise beans that you have deployment descriptor info for, add
a file to your XDoclet merge directory called weblogic-enterprise-beans.xml that contains
the <weblogic-enterprise-bean></weblogic-enterprise-bean> markup for those beans.
-->
<!--
To add a security-role-assignment section, add
a file to your XDoclet merge directory called weblogic-security-role-assignment.xml that contains
the <security-role-assignment></security-role-assignment> markup.
-->
<!--
To add a run-as-role-assignment section, add
a file to your XDoclet merge directory called weblogic-run-as-role-assignment.xml that contains
the <run-as-role-assignment></run-as-role-assignment> markup.
-->
</ weblogic-ejb-jar >
二。搭建spring web 项目环境,并配置applicationContext.xml如下:
<?
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 ="connectionFactory"
class ="org.springframework.jndi.JndiObjectFactoryBean" >
< property name ="jndiName" >
< value > helloConnectionFactory </ value >
</ property >
< property name ="jndiTemplate" >
< ref local ="jndiTemplate" ></ ref >
</ property >
</ bean >
< bean id ="destination"
class ="org.springframework.jndi.JndiObjectFactoryBean" >
< property name ="jndiName" >
< value > ejb/Hello </ value >
</ property >
< property name ="jndiTemplate" >
< ref local ="jndiTemplate" ></ ref >
</ property >
</ bean >
< bean id ="jmsTemplate"
class ="org.springframework.jms.core.JmsTemplate" >
< property name ="connectionFactory" >
< ref local ="connectionFactory" />
</ property >
< property name ="defaultDestination" >
< ref local ="destination" />
</ property >
</ bean >
< bean id ="jndiTemplate"
class ="org.springframework.jndi.JndiTemplate" >
< property name ="environment" >
< props >
< prop key ="java.naming.factory.initial" >
weblogic.jndi.WLInitialContextFactory
</ prop >
< prop key ="java.naming.provider.url" >
t3://localhost:7001
</ prop >
</ props >
</ property >
</ bean >
</ beans >
<! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd" >
< beans >
< bean id ="connectionFactory"
class ="org.springframework.jndi.JndiObjectFactoryBean" >
< property name ="jndiName" >
< value > helloConnectionFactory </ value >
</ property >
< property name ="jndiTemplate" >
< ref local ="jndiTemplate" ></ ref >
</ property >
</ bean >
< bean id ="destination"
class ="org.springframework.jndi.JndiObjectFactoryBean" >
< property name ="jndiName" >
< value > ejb/Hello </ value >
</ property >
< property name ="jndiTemplate" >
< ref local ="jndiTemplate" ></ ref >
</ property >
</ bean >
< bean id ="jmsTemplate"
class ="org.springframework.jms.core.JmsTemplate" >
< property name ="connectionFactory" >
< ref local ="connectionFactory" />
</ property >
< property name ="defaultDestination" >
< ref local ="destination" />
</ property >
</ bean >
< bean id ="jndiTemplate"
class ="org.springframework.jndi.JndiTemplate" >
< property name ="environment" >
< props >
< prop key ="java.naming.factory.initial" >
weblogic.jndi.WLInitialContextFactory
</ prop >
< prop key ="java.naming.provider.url" >
t3://localhost:7001
</ prop >
</ props >
</ property >
</ bean >
</ beans >
web.xml:
<?
xml version="1.0" encoding="UTF-8"
?>
<! DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >
< web-app id ="WebApp_ID" >
< display-name > p_spring </ display-name >
< context-param >
< param-name > contextConfigLocation </ param-name >
< param-value > /WEB-INF/applicationContext.xml </ param-value >
</ context-param >
< listener >
< listener-class >
org.springframework.web.context.ContextLoaderListener
</ listener-class >
</ listener >
< welcome-file-list >
< welcome-file > index.html </ welcome-file >
< welcome-file > index.htm </ welcome-file >
< welcome-file > index.jsp </ welcome-file >
< welcome-file > default.html </ welcome-file >
< welcome-file > default.htm </ welcome-file >
< welcome-file > default.jsp </ welcome-file >
</ welcome-file-list >
</ web-app >
<! DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >
< web-app id ="WebApp_ID" >
< display-name > p_spring </ display-name >
< context-param >
< param-name > contextConfigLocation </ param-name >
< param-value > /WEB-INF/applicationContext.xml </ param-value >
</ context-param >
< listener >
< listener-class >
org.springframework.web.context.ContextLoaderListener
</ listener-class >
</ listener >
< welcome-file-list >
< welcome-file > index.html </ welcome-file >
< welcome-file > index.htm </ welcome-file >
< welcome-file > index.jsp </ welcome-file >
< welcome-file > default.html </ welcome-file >
< welcome-file > default.htm </ welcome-file >
< welcome-file > default.jsp </ welcome-file >
</ welcome-file-list >
</ web-app >
weblogic.xml:
<?
xml version="1.0" encoding="UTF-8"
?>
<! DOCTYPE weblogic-web-app
PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN"
"http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd" >
< weblogic-web-app >
< jsp-descriptor >
< jsp-param >
< param-name > compileFlags </ param-name >
< param-value > -g </ param-value >
</ jsp-param >
< jsp-param >
< param-name > keepgenerated </ param-name >
< param-value > true </ param-value >
</ jsp-param >
</ jsp-descriptor >
< context-root > p_spring </ context-root >
</ weblogic-web-app >
<! DOCTYPE weblogic-web-app
PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN"
"http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd" >
< weblogic-web-app >
< jsp-descriptor >
< jsp-param >
< param-name > compileFlags </ param-name >
< param-value > -g </ param-value >
</ jsp-param >
< jsp-param >
< param-name > keepgenerated </ param-name >
< param-value > true </ param-value >
</ jsp-param >
</ jsp-descriptor >
< context-root > p_spring </ context-root >
</ weblogic-web-app >
编写spring调用ejb的测试类:
package
com.mdb.ejb;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
/** */ /**
* HelloBeanClient,用于发送消息。
*/
public class HelloBeanClient ... {
protected static final Log log = LogFactory.getLog(HelloBeanClient.class);
public static void main(String[] args) ...{
Resource resource = new ClassPathResource("applicationContext.xml");
BeanFactory factory = new XmlBeanFactory(resource);
JmsTemplate jt = (JmsTemplate) factory.getBean("jmsTemplate");
try ...{
for (int i = 0; i < 5; ++i) ...{
jt.send(new MessageCreator() ...{
public Message createMessage(Session session)
throws JMSException ...{
return session
.createTextMessage("Hello World(MDB),ejb/Hello!,"
+ System.currentTimeMillis());
}
});
}
} catch (Exception e) ...{
e.printStackTrace();
}
log.info("成功发送消息!");
}
}
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
/** */ /**
* HelloBeanClient,用于发送消息。
*/
public class HelloBeanClient ... {
protected static final Log log = LogFactory.getLog(HelloBeanClient.class);
public static void main(String[] args) ...{
Resource resource = new ClassPathResource("applicationContext.xml");
BeanFactory factory = new XmlBeanFactory(resource);
JmsTemplate jt = (JmsTemplate) factory.getBean("jmsTemplate");
try ...{
for (int i = 0; i < 5; ++i) ...{
jt.send(new MessageCreator() ...{
public Message createMessage(Session session)
throws JMSException ...{
return session
.createTextMessage("Hello World(MDB),ejb/Hello!,"
+ System.currentTimeMillis());
}
});
}
} catch (Exception e) ...{
e.printStackTrace();
}
log.info("成功发送消息!");
}
}
至此编码工作全部完成,整个项目的结构如下图:
三。在weblogic控制台
配置JMS 文件存储:
配置JMS 服务器:
配置JMS 队列:
配置JMS 连接工厂:
四。运行测试代码,运行结果如下: