在本地调用中,客户端和组件修改的是同一个对象。在编写Enterprise Bean时,应避免使用由这种传递方式带来的副作用,因为,当应用规模增长,客户端被分布到不同的物理服务器,参数的传递方式亦随之改变。
决定一个组件应该提供远程访问还是本地访问,一般有以下一些因素。
-
容器管理关系
如果某Entity Bean被其他Entity Bean所关联,则此Entity Bean必须提供本地访问接口。
?
-
相关Bean之间的耦合程度
耦合程度高的Bean之间存在互相依存的关系。因此,这一类Bean一般需要提供本地访问接口,以形成一个逻辑上的单元,同时提供整个单元内交互的效率。
?
-
客户端类型
如Bean将被JavaEE应用客户端所访问,则应该提供远程访问接口。如果客户端是Web组件或其他Bean,提供何种类型的访问接口决定于这些组件的分布状况。
?
-
组件分布
JavaEE应用可以分布在多个计算机,为提供这种分布上的可伸缩性,将被分布到不同位置的组件所访问的Bean,应该提供远程访问接口。
?
尽管一般Bean只提供一种类型的客户访问接口,但事实上,有一些Bean仍需要同时提供两种类型的接口
???? 一个很好的例子,比如
public void saveUser(User user) {
??System.out.println("User[name="+user.getName()+"]已被保存");
??user.setId(1);
?}
如果是remote调用的话:
???? ?UserManager ejb = (UserManager)ctx.lookup("UserManagerBean/remote");
??User user = new User();
??user.setName("张三");
??ejb.saveUser(user);
??
??System.out.println("用户【name="+user.getName()+",id="+user.getId()+"】已被成功保存!");
?
?? 输出的id依然为0,因为EJB改变了值,不会传给客户端的,
?? 如果用local的话,则可以输出id=1
?
4?标注的问题
?????如果ejb实现了多个接口,可以这样声明
/**
?* 定义方式1:
?* @Remote(value={Ejb04Interface01.class,Ejb04Interface02.class,Ejb04Interface03.class})
?* @Local(Ejb04Interface04.class)
?*/
@Stateless(name="Ejb04")
public class Ejb04Bean implements Ejb04Interface01,Ejb04Interface02,
??Ejb04Interface03,Ejb04Interface04 {
当然,也可以在各自的接口里加上@remote或@Local
?
5 webservice问题
直接加@webservice,详细的以后再小结之
6? 简单的JMS小结
P2P 和发布/订阅者模式,和EJB2的一样,这里就不列出来了.例子
p2p的:
mdb端:
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
@MessageDriven(
?activationConfig = {
??@ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Queue"),
??@ActivationConfigProperty(propertyName="destination",propertyValue="queue/myqueue")
?}
)
public class MyMDBBean implements MessageListener {
?public void onMessage(Message msg) {
??try {
???TextMessage textMessage = (TextMessage)msg;
???System.out.println("MyMDBBean被调用了!【"+textMessage.getText()+"】");
??} catch (JMSException e) {
???e.printStackTrace();
??}
?}
}
客户端消费:
public static void main(String[] args) throws Exception{
??InitialContext ctx = new InitialContext();
??
??//获取ConnectionFactory对象
??QueueConnectionFactory factory = (QueueConnectionFactory)ctx.lookup("ConnectionFactory");
??
??//创建QueueConnection对象
??QueueConnection connection = factory.createQueueConnection();
??
??//创建QueueSession对象,第一个参数表示事务自动提交,第二个参数标识一旦消息被正确送达,将自动发回响应
??QueueSession session = connection.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE);
??
??//获得Destination对象
??Queue queue = (Queue)ctx.lookup("queue/myqueue");
??
??//创建文本消息
??TextMessage msg = session.createTextMessage("世界,你好");
??
??//创建发送者
??QueueSender sender = session.createSender(queue);
??
??//发送消息
??sender.send(msg);
??
??//关闭会话
??session.close();
??
??System.out.println("消息已发送!");
?}
}
发布订阅者的话,其实就是把上面的queue改成TOPIC
?
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
@MessageDriven(
?activationConfig = {
??@ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Topic"),propertyValue="topic/mytopic")
?}
)
public class MyTopicMDBBean implements MessageListener {
?public void onMessage(Message msg) {
??try {
???TextMessage textMessage = (TextMessage)msg;
???System.out.println("MyTopicMDBBean被调用了!【"+textMessage.getText()+"】");
??} catch (JMSException e) {
???e.printStackTrace();
??}
?}
}
消费端:
?public static void main(String[] args) throws Exception{ ??InitialContext ctx = new InitialContext(); ?? ??//获取ConnectionFactory对象 ??TopicConnectionFactory factory = (TopicConnectionFactory)ctx.lookup("ConnectionFactory"); ?? ??//创建TopicConnection对象 ??TopicConnection connection = factory.createTopicConnection(); ?? ??//创建TopicSession对象,第一个参数表示事务自动提交,第二个参数标识一旦消息被正确送达,将自动发回响应 ??TopicSession session = connection.createTopicSession(false,TopicSession.AUTO_ACKNOWLEDGE); ?? ??//获得Destination对象 ??Topic topic = (Topic)ctx.lookup("topic/mytopic"); ?? ??//创建文本消息 ??TextMessage msg = session.createTextMessage("世界,你好"); ?? ??//创建发布者 ??TopicPublisher publisher = session.createPublisher(topic); ?? ??//发送消息 ??publisher.publish(msg); ?? ??//关闭会话 ??session.close(); ?? ??System.out.println("消息已发送!"); ?} ??