<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 78, comments - 34, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    2010-01-21 傳智播客—EJB

    Posted on 2010-01-22 11:40 長城 閱讀(346) 評論(0)  編輯  收藏

    EJB3的功能很是強大,但中小企業(yè)很少使用它做開發(fā),一般應(yīng)用SSH足以應(yīng)付。JAVAEE是做什么的?她是分布式企業(yè)級應(yīng)用的規(guī)范,那EJB就是為實現(xiàn)這樣的應(yīng)用而開發(fā)的。

    什么是分布式應(yīng)用?聽著名字很大。比如咱們的在線支付系統(tǒng),淘寶、china-pubamazon等都支持支付寶在線支付。難道它們分別都要將支付寶模塊放在自己的服務(wù)器上?完全沒必要。支付寶模塊單獨放在一個服務(wù)器上,其他服務(wù)器使用(調(diào)用)那一個服務(wù)器上的支付寶就可以了。在現(xiàn)實應(yīng)用中還有一些類似的將某一應(yīng)用模塊單獨取出放到另一個服務(wù)器上,供其他應(yīng)用使用。這就是分布式應(yīng)用了。(分布在不同的服務(wù)器上的應(yīng)用)

    一、JAVAEE回顧

    JAVAEE到底是什么呢?一圖更清(JavaEE5.0):

    wps_clip_image-9153

    昨天我們實現(xiàn)的EJB組件接口使用的是“@Local”注解,此注解只提供給本地調(diào)用。外部機器無法訪問。因為外部用戶與本地不在同一個虛擬機中。我們編寫的EJB組件不主要是給外部用戶訪問而使用分布試應(yīng)用嗎?正是。所以為了讓外部機器可以使用,我們需要將“@Local”注解修改為“@Remote”注解。在外部調(diào)用遠程的EJB組件時,應(yīng)該這樣使用:

    InitialContext ctx = new InitialContext();

    HelloWorld hw = (HelloWorld)ctx.lookup("HelloWorldBean/remote");

    String str = hw.sayHello("changcheng");

    二、EJB3中的EntityBean

    EJB3中的EntityBean就是POJOPlain old java object+注解,這方面的知識我們已經(jīng)在JPA中學(xué)習(xí)了。

    三、EJB3中的SessionBean

    SessionBean分為有狀態(tài)SessionBeanStateFulSessionBean-sfsb)和無狀態(tài)SessionBeanStateLessSessionBean-slsb)。

    1.StateLessSessionBean

    我們在之前是做的練習(xí)中,一般都有一個DAO層。DAO層不記錄用戶的狀態(tài),所以我們在使用EJB開發(fā)時,可以直接將DAO層定義為無狀態(tài)Bean

    如何定義無狀態(tài)Bean,我們在昨天的練習(xí)中使用的就是無狀態(tài)Bean。直接在類上添加“@Stateless”注解,即可將類定義為無狀態(tài)的Bean

    每次產(chǎn)生一個新的會話,EJB容器需要為會話創(chuàng)建相關(guān)的無狀態(tài)Bean對象,無疑這會為服務(wù)器帶來極大的資源開銷。我們在學(xué)習(xí)JDBC時,使用了線程池專門用來處理用戶與數(shù)據(jù)庫的連接。因為無狀態(tài)Bean不記錄用戶的狀態(tài),所以EJB3中也定義了無狀態(tài)的Bean池。這樣大大節(jié)省了用戶訪問的時間與服務(wù)器資源的開銷。

    無狀態(tài)Bean具有兩個事件,創(chuàng)建后和銷毀前。我們在方法上添加“@PostConstruct”注解,此方法將在無狀態(tài)Bean創(chuàng)建后調(diào)用,我們在方法上添加“@PreDestroy”注解,此方法將在無狀態(tài)Bean銷毀后被調(diào)用。

    2.StateFulSessionBean

    有狀態(tài)Bean的典型案例是購物車,購物車需要記錄用戶購買的商品,所以它是有狀態(tài)的Bean。我們知道無狀態(tài)BeanBean池,那有狀態(tài)Bean可否有Bean池呢?當(dāng)然不可以。所以有狀態(tài)Bean會給服務(wù)器帶來極大的負擔(dān),能不用有狀態(tài)Bean就不要使用有狀態(tài)Bean

    EJB3中也盡量減少有狀態(tài)Bean所帶來的負載,所以EJB3為有狀態(tài)Bean添加了鈍化和激活的功能。比如用戶在超市購物,用戶剛進入超市時推起購物車(CartBean對象,這個有狀態(tài)Bean被創(chuàng)建)。當(dāng)用戶選擇商品并謝謝購物車時(向CartBean對象添加狀態(tài))。突然用戶有急事要離開一會,工作人員將購物車推到“等候區(qū)”(CartBean對象被鈍化)。用戶處理完事物之后回來繼續(xù)購物,到“等候區(qū)”推出自己的購物車(CartBean對象被激活)。用戶結(jié)賬工取消購物時(CartBean對象被刪除)。

    EJB3中正是使用方法減少頻繁創(chuàng)建有狀態(tài)Bean所給服務(wù)器帶來的負擔(dān),同時也為用戶提供了方便。

    EJB3中有狀態(tài)Bean的事件:

    1).有狀態(tài)Bean被創(chuàng)建后:在某一方法上添加“@PostConstruct”注解,有狀態(tài)Bean被創(chuàng)建后會調(diào)用此方法。

    2).有狀態(tài)Bean被鈍化:在某一方法上添加“@PrePassivate”注解,調(diào)用此方法后,有狀態(tài)Bean被鈍化。EJB3容器會將此Bean序列化后,保存到硬盤上,并從內(nèi)存中刪除。有狀態(tài)Bean需要實現(xiàn)“Serializable”接口。

    3).有狀態(tài)Bean被激活:在某一方法上添加“@PostActivate”注解,調(diào)用此方法后,有狀態(tài)Bean被激活。EJB3容器會將此Bean反序列化后,放到內(nèi)存中,并刪除硬盤上的內(nèi)容。

    4).有狀態(tài)Bean被銷毀前:在某一方法上添加“@PreDestroy”注解,無狀態(tài)Bean被銷毀前會調(diào)用此方法。

    5).有狀態(tài)Bean被刪除:在某一方法上添加“@Remove”注解,調(diào)用此方法后,通知EJB3容器刪除有狀態(tài)Bean。如果不添加“@Remove”注解,客戶端將沒有任何方式告訴服務(wù)器終止會話,結(jié)果將導(dǎo)致SFSB在超時后進行鈍化至磁盤,再次超時后將對象銷毀。在高并發(fā)的系統(tǒng)當(dāng)中,無疑會有嚴重的性能問題。內(nèi)存開銷會居高不下,更不要提占用cpu和磁盤空間了。

    四、EJB3中的消息驅(qū)動Bean

    EJB3中的消息驅(qū)動分為隊列消息(queue)和主題消息(Topic),是一種異步消息驅(qū)動。

    1.隊列消息

    發(fā)送消息:

    import javax.jms.*;

    import javax.naming.InitialContext;

    /**

     * 隊列消息驅(qū)動bean

     */

    public class MDBQueueApp {

    public static void main(String[] args) throws Exception {

    InitialContext ctx = new InitialContext();

    //通過JNDI查找隊列連接工廠,EJB自身包含的。

    QueueConnectionFactory qcf = (QueueConnectionFactory) ctx.lookup("QueueConnectionFactory");

    //通過連接工廠創(chuàng)建隊列連接

    QueueConnection qc = qcf.createQueueConnection();

    //通過隊列連接創(chuàng)建隊列會話

    QueueSession qs = qc.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);

    //通過JNDI查找可用隊列,EJB3自身包含的。

    Queue queue = (Queue) ctx.lookup("queue/testQueue");

    //通過隊列會話創(chuàng)建到指定隊列的消息生產(chǎn)者

    MessageProducer mp = qs.createProducer(queue);

    //通過隊列回話創(chuàng)建文本消息

    TextMessage msg = qs.createTextMessage();

    msg.setText("Hi,你好嗎?隊列消息");

    //通過消息的生產(chǎn)者發(fā)送消息

    mp.send(msg);

    //釋放資源

    qs.close();

    qc.close();

    System.out.println("隊列消息發(fā)送完畢!");

    }

    }

    接收消息:

    import javax.ejb.*;

    import javax.jms.*;

    @MessageDriven(activationConfig={@ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Queue"),@ActivationConfigProperty(propertyName="destination",propertyValue="queue/testQueue")})

    public class MyQueueMDB implements MessageListener {

    public void onMessage(Message arg0) {

    if(arg0 instanceof TextMessage){

    try {

    System.out.println("收到消息隊列消息 : " + ((TextMessage)arg0).getText());

    System.out.println("I'm fine,Thank you!");

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

    }

    隊列消息只能被一個接收都接收到,隊列消息一旦被某個接收者接收到后,消息將從隊列中消失。所以其他接收同一隊列消息的接收者無法收到。這個第一個接收到隊列消息的接收者是最后一次被添加的接收者。

    2.主題消息

    發(fā)送消息:

    import javax.jms.*;

    import javax.naming.InitialContext;

    /**

     * 主題消息驅(qū)動bean

     */

    public class MDBAppTopic {

    public static void main(String[] args) throws Exception {

    InitialContext ctx = new InitialContext();

    //通過JNDI查找主題連接工廠,EJB3自身包含的。

    TopicConnectionFactory tcf = (TopicConnectionFactory) ctx.lookup("TopicConnectionFactory");

    //通過連接工廠創(chuàng)建主題連接

    TopicConnection tc = tcf.createTopicConnection();

    //通過主題連接創(chuàng)建主題會話

    TopicSession ts = tc.createTopicSession(false,Session.AUTO_ACKNOWLEDGE);

    //通過JNDI查找可用主題,EJB3自身包含的。

    Topic topic = (Topic) ctx.lookup("topic/testTopic");

    //通過主題會話創(chuàng)建到指定主題的消息生產(chǎn)者

    MessageProducer mp = ts.createProducer(topic);

    //通過主題回話創(chuàng)建文本消息

    TextMessage msg = ts.createTextMessage();

    msg.setText("Hi,你好嗎?(主題消息)");

    //通過消息的生產(chǎn)者發(fā)送消息

    mp.send(msg);

    //釋放資源

    ts.close();

    tc.close();

    System.out.println("主題消息發(fā)送完畢!");

    }

    }

    接收消息:

    import javax.ejb.*;

    import javax.jms.*;

    @MessageDriven(activationConfig={@ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Topic"),@ActivationConfigProperty(propertyName="destination",propertyValue="topic/testTopic")})

    public class MyTopicMDB implements MessageListener {

    public void onMessage(Message arg0) {

    if(arg0 instanceof TextMessage){

    try {

    System.out.println("收到主題消息 : " + ((TextMessage)arg0).getText());

    System.out.println("我很好,謝謝!");

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

    }

    主題消息是一種共享模式,相當(dāng)于群。每個消息被當(dāng)做主題,群內(nèi)的所有成員都可以收到。

    五、ANT

    我們編寫EJB組件和WEB應(yīng)用時,需要手動打成JARWAR包并放置到JBOSSdeploy目錄中。這顯然是不理想的操作方式,我們每測試一個功能都這樣做嗎?ANT可以幫助我們解決這個問題。

    當(dāng)一個代碼項目大了以后,每次重新編譯,打包,測試等都會變得非常復(fù)雜而且重復(fù),因此c語言中有make腳本來幫助這些工作的批量完成。在Java 中應(yīng)用是平臺無關(guān)性的,當(dāng)然不會用平臺相關(guān)的make腳本來完成這些批處理任務(wù)了,ANT本身就是這樣一個流程腳本引擎,用于自動化調(diào)用程序完成項目的編譯,打包,測試等。除了基于JAVA是平臺無關(guān)的外,腳本的格式是基于XML的,比make腳本來說還要好維護一些。 

    ANT IN ACTION 2)》是一本專門調(diào)解ANT的書籍,在此就不多總結(jié)了。


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 一个人看的免费高清视频日本 | 亚洲AV日韩精品一区二区三区| 久久福利青草精品资源站免费| 亚洲a∨无码一区二区| 久久亚洲精品人成综合网| 又大又硬又爽免费视频| 久久不见久久见中文字幕免费| 久久免费线看线看| 一级特黄色毛片免费看| 国产精品亚洲专区无码WEB| 亚洲日本在线观看网址| 亚洲av网址在线观看| 亚洲综合最新无码专区| www国产亚洲精品久久久日本| 成年女人18级毛片毛片免费 | 亚洲成av人影院| 亚洲人成网站观看在线播放| 国产无遮挡又黄又爽免费视频| 成年免费大片黄在线观看岛国| 99re6免费视频| 外国成人网在线观看免费视频| 国产综合免费精品久久久| 深夜福利在线免费观看| 国产亚洲精品AAAA片APP | 成在线人永久免费视频播放| 国产精品视频免费观看| 777成影片免费观看| 99re这里有免费视频精品 | 亚洲天堂中文字幕| 亚洲VA中文字幕无码一二三区 | 免费国产成人午夜在线观看| 久久免费香蕉视频| 国产成人1024精品免费| 久久精品无码专区免费| 最近免费中文字幕MV在线视频3| 一个人看的www视频免费在线观看 一个人看的免费观看日本视频www | 男男AV纯肉无码免费播放无码| 国产h肉在线视频免费观看| 亚洲人成在线免费观看| 1024免费福利永久观看网站| 18禁止观看免费私人影院|