Let's go inside

this blog is deprecated as a result of laziness.
posts - 59, comments - 2, trackbacks - 0, articles - 0

实战-菜鸟也学EJB3

Posted on 2006-07-19 11:49 Earth 阅读(348) 评论(0)  编辑  收藏 所属分类: JavaEE5/EJB3

花了一段时间下载了jboss-4.0.4.GA, jboss-EJB-3.0_RC8-FD, JBossIDE-1.5.1.GA-Bundle-win32
按照jboss-EJB-3.0_RC8-FD中install.htm中的配置指南(有问题,解决办法见fisheye.jboss),我不是完全按照它来做的,因为我使用的是 default目录,而没有使用all.

一切准备好后,我先是直接在Eclipse中把Enterprise Javabean第五版中的例一跑了一遍,成功了。
接下来按照菜鸟也学EJB1,2,3,4系列(http://willbe.xinwen365.net/ejb3-4.htm )全部跑了一遍,感觉还不错。下面是测试SLSB和SFSB区别的例子(有改动)

@Remote
public   interface  Say {
    
public  String say();
    
public  @Remove String goodBye();
}


public  @Stateful  class  SayBean  implements  Say {
    
private   int  i  =   0 //  SayBean自己的状态

    
public  String say() {
        i
++ ;
        
return   " Hello World!  "   +  i;
    }

    
public  String goodBye() {
        
return   " bye, bye " ;
    }
}

public   class  Client {
    
public   static   void  main(String[] args)  throws  Exception {
        InitialContext ctx 
=   new  InitialContext();
        Say say 
=  (Say) ctx.lookup( " SayBean/remote " );
        System.out.println(say.say());
        System.out.println(say.goodBye());
        
try  {
            System.out.println(say.say());
        } 
catch  (RuntimeException e) {
            System.err.println(
" goodBye in Stateful sessionbean destroys everything! " );
            e.printStackTrace();
        }
    }
}


当SayBean标记为@Stateful时,多次调用的结果始终相同,
因为客户和Stateful SessionBean(有状态会话Bean)的关系是一对一的关系,当客户调用销毁方法(带@Remove标签的方法)时,服务器就会销毁该对象,即使注释掉最后一句——不调用销毁方法,系统依然会销毁该有状态会话Bean.

另外,如果显示调用它的销毁方法后试图重新使用它的时候就抛出异常:javax.ejb.EJBNoSuchObjectException: Could not find Stateful bean(这里留一个问题,我上面的代码怎么没有抛出异常?)

当SayBean标记为@Stateless时,每次调用的结果都不同,因为客户和Stateless SessionBean(无状态会话Bean)的关系是多对一的关系,即使每次调用后say.say()后均调用它的销毁方法say.goodBye(),系统也不会销毁无状态会话Bean.

还有一个送玫瑰和介指的例子,和这个大同小异。

今天,你给消息驱动了吗?

@MessageDriven(activationConfig  =  {
    @ActivationConfigProperty(propertyName 
=   " destinationType " , propertyValue  =   " javax.jms.Queue " ),
    @ActivationConfigProperty(propertyName 
=   " destination " , propertyValue  =   " queue/mytest/test " ) })
public   class  TestDriven  implements  MessageListener {
    
public   void  onMessage(Message arg0) {
        System.out.println(
" 我是中国第一个玩EJB3菜鸟级人物! " );
    }
}

我们的TestDriven类实现了MessageListener接口,所以,我们有理由相信他就是一个监听器.,原来消息驱动Bean是一个监听器哦~_~. 我们还看到了一个onMessage方法, 这个不就是我们的onClick() onEnter() onClose()等等on系列的兄弟吗? 他怎么升级了,跑到j2ee里面去了.呵呵,看来我们的onClick(),onEnter()等兄弟们要加倍努力呀.看看那sun公司肯不肯也收留我们这帮兄弟.我们还看到了@MessageDriven这个东东,嗯,原来这是个老大来的,他说得算,如果没有他,这个TestDriven就不是MessageDrivenBean(消息驱动Bean)了..
好吧,我们先不管三七二十一,写些东东到方法onMessage(Message arg0)里面,看看有没有什么不良反映(~_~看他会不会吃错药).. 那就加个 System.out.println(“我是中国第一个玩EJB3菜鸟级人物”);

public   class  Client {
    
public   static   void  main(String[] args)  throws  Exception {
        QueueConnection cnn 
=   null ;
        QueueSender sender 
=   null ;
        QueueSession session 
=   null ;

        
//  创建上下文环境,这个是什么东东,呵呵,我们以前谈过了.
        InitialContext ctx  =   new  InitialContext(ht);

        
//  该参数为驱动该TestDriven的队列,我们后面会详细说明
        Queue queue  =  (Queue) ctx.lookup( " queue/mytest/test " );

        
//  这位大哥可真贪心,lookup了驱动队列,还要lookup队列的连接工厂..还是有点复杂喲!我的消息驱动Bean兄弟
        QueueConnectionFactory factory  =  (QueueConnectionFactory) ctx
                .lookup(
" ConnectionFactory " );

        
//  创建队列连接
        cnn  =  factory.createQueueConnection();

        
//  由连接创建回话
        session  =  cnn.createQueueSession( false , QueueSession.AUTO_ACKNOWLEDGE);

        
//  把字符串打包成一个消息
        TextMessage msg  =  session.createTextMessage( " Hello World " );

        
//  由回话(session)创建到目标驱动队列的发送者
        sender  =  session.createSender(queue);

        
//  发射,呵呵,神州六号好像也是这样发送的吧.
        sender.send(msg);

        
//  开始得意洋洋了.~_~
        System.out.println( " 我已经成功地驱动了那个鸟人(消息驱动Bean)! " );
    }
}


看到顺序了吗:  首先通过ctx 从jndi大哥那里偷到ConnectionFactory(连接工厂)这个宝贝,然后那,然后由我们的连接工厂去创建连接,然后由连接创建回话,然后由回话根据目标队列创建发送者,然后就发送吧.
    呵呵,晕了吧,其实那个东东是所谓的那些牛人写了一本叫做<<设计模式>>的书,刚才那里的代码就是他里面说的典型的工厂模式. 反正呢. 以为,我们的代码要依赖于jndi大哥,所以只能这位大哥说得算,你用new去创建对象,人家大哥就不同意,他会觉得没面子.呵呵.(说笑)..

最后是一个queue-service.xml的文件,布署的时候要放到deploy目录下,JBoss自动检测到这个不知道什么东西的文件,然后打印出[mytest] Bound to JNDI name: queue/mytest/test,原来这个文件就是叫JBoss服务器去帮定一个队列queue/mytest/test,这样然后在客户端就可以用 Queue queue = (Queue) ctx.lookup("queue/mytest/test")从InitialContext把它取出来

<? xml version="1.0" encoding="UTF-8" ?>
< server >
 
< mbean  code ="org.jboss.mq.server.jmx.Queue"
  name
="jboss.mq.destination:service=Queue,name=mytest" >
  
  
< attribute  name ="JNDIName" > queue/mytest/test </ attribute >
  
  
< depends  optional-attribute-name ="DestinationManager" >
   jboss.mq:service=DestinationManager
</ depends >
  
 
</ mbean >
</ server >

更多关于使用EJB3的东东有待继续看书看例子,之后我会陆续写或转载些东西,尽请关注


只有注册用户登录后才能发表评论。


网站导航: