posts - 66,  comments - 11,  trackbacks - 0
              時(shí)間到了,繼續(xù)我心中的那個(gè)她,每天晚上堅(jiān)持寫(xiě)博客,感覺(jué)真的很好,我想把自己所想的寫(xiě)出來(lái)。這兩天出奇的冷,北京的天氣真郁悶,是不是后天要來(lái)了,這種溫度讓我的大腦都結(jié)冰了,都語(yǔ)無(wú)倫次了,雖然很冷,但是,還是要用我那冰冷的手指敲打鍵盤(pán)。
              昨天說(shuō)到美女生氣了,她的沉默使我也很沉默,我也不是怎么會(huì)哄女孩的人,天生的呆板,屬于榆木腦袋那種,只能等她心情好的時(shí)候跟她多說(shuō)幾句話。還好沒(méi)過(guò)幾天,她的心情多云轉(zhuǎn)晴,我也就自然的晴天了。過(guò)了段時(shí)間,作為我對(duì)她細(xì)心培訓(xùn)的回報(bào),她要請(qǐng)我吃飯。這頓飯可把我害苦了,就是從這頓飯后,每天腦子里都是她的身影(有點(diǎn)過(guò)了),但是每當(dāng)想到她的時(shí)候,腦袋就亂,而且很不舒服。吃飯那天自己都不知道說(shuō)了些什么,本來(lái)有很多話要說(shuō)的,但是不知為什么,沒(méi)有說(shuō)出口。回家的時(shí)候她把我送到了車(chē)站,在回家的車(chē)上,腦子一片空白。還好自己知道在哪里下車(chē),出站的時(shí)候突然感覺(jué)自己好像丟了什么,心里空蕩蕩的,原來(lái)把自己的心丟了,以前在學(xué)校的時(shí)候,知道沒(méi)有思想的痛苦,跟她吃了頓飯,知道了沒(méi)有心的痛苦,沒(méi)有心的感覺(jué)真好,不管身心如何痛苦,時(shí)間不會(huì)因?yàn)槟愣V梗钸€在繼續(xù)。以后的日子里,就不用說(shuō)了,每天都在快樂(lè)并痛苦著,每天白天能有她相伴在身邊是快樂(lè)的,下班回家之后想她是痛苦的。
              時(shí)間一點(diǎn)點(diǎn)的流逝,轉(zhuǎn)眼快到10.1了,大家都在討論放假回家什么的,說(shuō)到這里有點(diǎn)對(duì)不起自己的父母了,我離家里比較近,動(dòng)車(chē)也就3個(gè)小時(shí)的路程,但是每年只有過(guò)年的時(shí)候才回家一次,感覺(jué)跟家里人相聚的時(shí)間太短了,愧對(duì)自己的父母,沒(méi)辦法啊,我們這種在外面漂流的人...說(shuō)她吧,那次聽(tīng)到她要回家買(mǎi)票難什么的,我也沒(méi)打算幫她買(mǎi),我也沒(méi)有那么大的本事,事情湊巧,以前的一個(gè)朋友打電話聊天,我想到他是做導(dǎo)游的應(yīng)該很方便弄票,于是就跟兄弟說(shuō)了一聲,兄弟是答應(yīng)了,但是我當(dāng)她說(shuō)的時(shí)候,她卻說(shuō)不用了(因?yàn)椴恢雷龌疖?chē)還是汽車(chē)),這是明顯的搪塞,那天我生氣了,生氣的不是因?yàn)樗氯且驗(yàn)樗遣焕洳粺帷⒛魂P(guān)心的態(tài)度,氣的我和她保持沉默了,但是工作上的關(guān)系,又不得不說(shuō)話。還好我的天氣也不是那種南方的陰雨連綿,過(guò)幾天就好了,這樣我們還保持著普通朋友的關(guān)系。
              明天就結(jié)束我們2個(gè)月的關(guān)系了,自己都沒(méi)想到,想一個(gè)人會(huì)是這個(gè)樣子,可能她不適合我,我也不適合她,朋友們都說(shuō),自己都做程序員了,還找個(gè)程序員做老婆。不合適,我也這么覺(jué)得。希望我們能成為好朋友,如果你給我當(dāng)朋友的話,我也會(huì)視你為我的朋友。你只能活在我的記憶中了,不是我的心底。因?yàn)槟銢](méi)有走進(jìn)我。
              時(shí)間真快,又一個(gè)小時(shí)了,明天早起去吃早餐,^_^,天氣涼了,胃口上來(lái)了。
              Good night 我的那個(gè)她。

          posted @ 2009-11-03 00:15 王永慶 閱讀(261) | 評(píng)論 (3)編輯 收藏
              會(huì)話Bean同其他企業(yè)Bean類(lèi)型最主要的區(qū)別是生命周期的差異性。會(huì)話Bean實(shí)例是存活短暫的對(duì)象,會(huì)話Bean實(shí)例并不能夠在多客戶(hù)間共享。
              通常,客戶(hù)會(huì)話的持續(xù)期決定了使用中的會(huì)話Bean的存活期,一旦應(yīng)用服務(wù)器癱瘓,會(huì)話Bean實(shí)例也應(yīng)該不復(fù)存在。因?yàn)椋瑫?huì)話Bean僅僅是內(nèi)存對(duì)象,一旦其生存的周邊環(huán)境遭到破壞,會(huì)話Bean也將不復(fù)存在。會(huì)話Bean并不是持久化的,因此,會(huì)話Bean并不會(huì)保存到持久化存儲(chǔ)源中,這同實(shí)體Bean不一樣,會(huì)話Bean能夠操作RDBMS,但是其本身并不是持久化對(duì)象。
              會(huì)話指客戶(hù)同EJB組件的交互,它由客戶(hù)和EJB組件間的多次方法調(diào)用構(gòu)成。會(huì)話Bean存在2種子類(lèi)型:有狀態(tài)會(huì)話Bean和無(wú)狀態(tài)會(huì)話Bean,各自用于建模不同類(lèi)型的會(huì)話。有狀態(tài)會(huì)話Bean是這樣一種EJB,即其服務(wù)的業(yè)務(wù)過(guò)程能夠延伸到多個(gè)方法請(qǐng)求或者事務(wù)中,為完成這種業(yè)務(wù)過(guò)程,有狀態(tài)會(huì)話Bean需要為單個(gè)客戶(hù)保存狀態(tài)信息。如果在方法調(diào)用期間有狀態(tài)會(huì)話Bean的狀態(tài)發(fā)生改變,則這種改變必須反映到同一客戶(hù)的隨后調(diào)用中。無(wú)狀態(tài)會(huì)話Bean是這樣一種EJB,即其服務(wù)的業(yè)務(wù)過(guò)程只需要單個(gè)業(yè)務(wù)方法即可完成。由于他們不需維護(hù)客戶(hù)多個(gè)方法調(diào)用間的會(huì)話狀態(tài),因此它是無(wú)狀態(tài)的。在每次方法調(diào)用結(jié)束后,EJB容器可能會(huì)銷(xiāo)毀無(wú)狀態(tài)會(huì)話Bean實(shí)例,或者實(shí)例化新的實(shí)例,或者清楚掉上次方法調(diào)用中的相關(guān)信息。
              無(wú)狀態(tài)意指不存在會(huì)話狀態(tài)。無(wú)狀態(tài)會(huì)話Bean能夠含有同特定客戶(hù)不相關(guān)的狀態(tài)信息,比如所有客戶(hù)將使用到數(shù)據(jù)庫(kù)鏈接工廠,開(kāi)發(fā)者可以將它存儲(chǔ)在private變量中。如果開(kāi)發(fā)者將數(shù)據(jù)存儲(chǔ)在private變量中,則將隨時(shí)丟失其中存儲(chǔ)的數(shù)據(jù)。
              EJB容器將維護(hù)EJB實(shí)例池,而且這些EJB實(shí)例是可重用的。在每次方法調(diào)用時(shí),都會(huì)有不同EJB實(shí)例或同一實(shí)例服務(wù)客戶(hù)。為了限制內(nèi)存中運(yùn)行的有狀態(tài)會(huì)話Bean實(shí)例的數(shù)量,EJB容器需要將有狀態(tài)會(huì)話Bean的會(huì)話狀態(tài)保存到硬盤(pán)或者其他存儲(chǔ)源中。該過(guò)程稱(chēng)之為掛起。在掛起有狀態(tài)會(huì)話Bean后,會(huì)話狀態(tài)被安全的保存下來(lái),而且其釋放的內(nèi)存可以供其他應(yīng)用使用。一旦被掛起的有狀態(tài)會(huì)話Bean實(shí)例的客戶(hù)再次調(diào)用它,被掛起的會(huì)話狀態(tài)將重新回到有狀態(tài)會(huì)話Bean實(shí)例中,該過(guò)程稱(chēng)之為激活。
              有狀態(tài)會(huì)話Bean實(shí)例的會(huì)話狀態(tài)必須遵循Java對(duì)象序列化設(shè)定的規(guī)則。在掛起有狀態(tài)會(huì)話Bean實(shí)例時(shí),EJB容器借助于對(duì)象序列化將會(huì)話狀態(tài)轉(zhuǎn)換成二進(jìn)制blob,然后將它寫(xiě)入到硬盤(pán)中。在轉(zhuǎn)移會(huì)話狀態(tài)信息后,有狀態(tài)會(huì)話Bean實(shí)例(指刮起了會(huì)話狀態(tài)的那些EJB實(shí)例)還能夠服務(wù)于其他客戶(hù),即同新的客戶(hù)進(jìn)行新的會(huì)話過(guò)程。

              一旦EJB中的成員變量符合如下條件,則可以認(rèn)為它是會(huì)話狀態(tài)的組成部分之一。
          1、成員變量是非transient類(lèi)型的java原始類(lèi)型。
          2、成員變量是非transient類(lèi)型的Java對(duì)象類(lèi)型。
              當(dāng)容器將EJB實(shí)例掛起時(shí),它需要將實(shí)例的會(huì)話狀態(tài)寫(xiě)入到二級(jí)存儲(chǔ)源中,比如文件或者RDBMS中。通過(guò)調(diào)用EJB實(shí)例的ejbPassivate()回調(diào)方法,容器能夠完成實(shí)例的掛起工作。借助于ejbPassivate()方法能夠告知EJB實(shí)例:EJB容器需要掛起它,這使得釋放其持有的資源成為可能。比如EJB實(shí)例可能持有的資源有:RDBMS連接、已打開(kāi)的Socket和文件或者其他任何資源。
              在實(shí)際場(chǎng)合中,客戶(hù)調(diào)用了EJB對(duì)象中的某個(gè)方法,而當(dāng)時(shí)在內(nèi)存中暫時(shí)找不到該EJB對(duì)象,與此同時(shí),EJB容器持有的企業(yè)Bean實(shí)例的個(gè)數(shù)已經(jīng)到達(dá)了設(shè)定的上限。因此在處理客戶(hù)請(qǐng)求前,容器需要掛起最近未使用的EJB實(shí)例,在掛起它后,容器才能夠獲得所需的EJB對(duì)象。
              有狀態(tài)會(huì)話Bean的部署描述符。
             
          <?xml version="1.0" encoding="UTF-8"?>
          <ejb-jar version="2.1" xmlns="http://java.sun.com/xml/ns/j2ee"
           xmlns:xsi
          ="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation
          ="http://java.sun.com/xml/ns/j2ee
           http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"
          >
              
          <enterprise-beans>
                  
          <session>
                      
          <ejb-name>Count</ejb-name>
                      
          <home>examples.CountHome</home>
                      
          <remote>examples.Count</remote>
                      
          <ejb-class>examples.CountBean</ejb-class>
                      
          <session-type>Stateful</session-type>
                      
          <transaction-type>Container</transaction-type>
                  
          </session>
              
          </enterprise-beans>
          </ejb-jar>

          服務(wù)端企業(yè)Bean:
          package com.wyq.ejb02;

          import java.rmi.RemoteException;

          import javax.ejb.CreateException;
          import javax.ejb.EJBException;
          import javax.ejb.SessionBean;
          import javax.ejb.SessionContext;
          /**
           * 演示有狀態(tài)Bean
           * 它會(huì)初始化val,并提供業(yè)務(wù)方法。
           * 該實(shí)例演示了最簡(jiǎn)單的有狀態(tài)會(huì)話Bean,并給出了掛起、激活的工作機(jī)理。
           
          */
          public class CountBean implements SessionBean {
              
          //會(huì)話狀態(tài)
              public int val;
              
          //業(yè)務(wù)方法
              public int count(){
                  System.out.println(
          "count");
                  
          return ++val;
              }
              
          public void ejbCreate(int val)throws CreateException{
                  
          this.val = val;
                  System.out.println(
          "ejbCreate()");
              }
              
          public void ejbActivate() throws EJBException, RemoteException {
                  System.out.println(
          "ejbActivate()");
              }

              
          public void ejbPassivate() throws EJBException, RemoteException {
                  System.out.println(
          "ejbPassivate()");
              }

              
          public void ejbRemove() throws EJBException, RemoteException {
                  System.out.println(
          "ejbRemove()");
              }

              
          public void setSessionContext(SessionContext ctx) throws EJBException,
                      RemoteException {
              }

          }
          客戶(hù)端調(diào)用:
          package com.wyq.ejb02;

          import java.util.Properties;

          import javax.naming.Context;
          import javax.naming.InitialContext;

          import com.wyq.ejb01.HelloHome;
          /**
           * 1、獲得JNDI InitialContext上下文。
           * 2、借助于JNDI,定義Home對(duì)象。
           * 3、使用Home對(duì)象創(chuàng)建3個(gè)不同的CountEjb對(duì)象。因此,這將建立起3個(gè)不同的會(huì)話過(guò)程,而且模擬了3個(gè)不同的客戶(hù)。
           * 4、由于內(nèi)存中僅能存活2個(gè)EJB實(shí)例,因此在創(chuàng)建Count EJB實(shí)例期間,EJB容器需要完成實(shí)例的掛起操作。
           * 5、調(diào)用各個(gè)EJB對(duì)象的count()方法。
           * 6、最后,刪除所有的EJB對(duì)象。
           
          */
          public class CountClient {

              
          /**
               * 客戶(hù)代碼示例
               * 
               * 此時(shí),創(chuàng)建了3個(gè)EJB對(duì)象。但我們規(guī)定容器:在內(nèi)存中最多存在2個(gè)實(shí)例。
               * 因?yàn)椋軌蚩吹綊炱鸩僮鞯陌l(fā)生。
               
          */
              
          public static void main(String[] args) {
                  
          try{
                      
          /*
                       * 獲得JNDI環(huán)境屬性
                       
          */
                      Properties props 
          = System.getProperties();
                      
          /*
                       * 獲得對(duì)Home對(duì)象的引用,Home對(duì)象是EJB對(duì)象的工廠
                       
          */
                      Context ctx 
          = new InitialContext(props);
                      
                      Object obj 
          = ctx.lookup("CountHome");
                      
                      CountHome home 
          =(CountHome)javax.rmi.PortableRemoteObject.narrow(obj,CountHome.class);
                      
          /*
                       * 能夠持有3個(gè)Count對(duì)象的數(shù)組 
                       
          */
                      Count count[] 
          = new Count[3];
                      
          int countVal = 0;
                      
          /*
                       * 創(chuàng)建EJB實(shí)例,并調(diào)用各自的count()
                       
          */
                      System.out.println(
          "Instantiating beans");
                      
          for(int i=0;i<3;i++){
                          
          /*
                           * 創(chuàng)建EJB對(duì)象,并初始化它們
                           
          */
                          count[i]  
          = home.create(countVal);
                          
          /*
                           * 加1,并打印出來(lái)
                           
          */
                          countVal 
          = count[i].count();
                          System.out.print(countVal);
                          
          /*
                           * 等待1/2秒
                           
          */
                          Thread.sleep(
          500);
                      }
                      
          /*
                       * 調(diào)用各個(gè)EJB對(duì)象的count()方法,從而能夠?yàn)g覽到EJB被掛起,并被成功激活
                       
          */
                      System.out.println(
          "Calling count() on beans");
                      
          for(int i=0;i<3;i++){
                          
          /*
                           * 加1,并打印出來(lái)
                           
          */
                          countVal 
          = count[i].count();
                          System.out.println(countVal);
                          
          /*
                           * 等待1/2秒
                           
          */
                          Thread.sleep(
          500);
                      }
                      
          /*
                       * 使用完后,銷(xiāo)毀它們
                       
          */
                      
          for(int i=0;i<3;i++){
                          count[i].remove();
                      }
                  }
          catch(Exception e){
                      e.printStackTrace();
                  }

              }

          }

          會(huì)話Bean的聲明周期流程圖
          1、起初,EJB實(shí)例并不存在。
          2、EJB容器將決定是否需要實(shí)例化新的EJB實(shí)例。容器將何時(shí)實(shí)例化新的EJB實(shí)例,取決于容器使用的EJB實(shí)例池策略。
          3、容器實(shí)例化EJB Bean類(lèi)。EJB容器將調(diào)用Class.newInsatance("HelloBean.class");即動(dòng)態(tài)創(chuàng)建HelloBean實(shí)例,這使得容器不會(huì)將EJBBean類(lèi)的名字硬編碼在Java代碼中。最后,這使得容器更具通用性,能夠操控任何企業(yè)Bean.
          4、容器調(diào)用setSessionContext()方法。這為EJB實(shí)例設(shè)置了上下文對(duì)象。最終,EJB實(shí)例將能夠訪問(wèn)到EJB容器。
          5、容器調(diào)用ejbCreate().這將初始化EJB實(shí)例。由于無(wú)狀態(tài)會(huì)話Bean的ejbCreate()方法并不存在參數(shù),因此EJB客戶(hù)不可能為它提供任何啟動(dòng)EJB實(shí)例的參數(shù)信息。
          6、EJB容器調(diào)用EJB實(shí)例的業(yè)務(wù)方法。對(duì)于EJB實(shí)例提供的所有業(yè)務(wù)方法,EJB容器都可以使用。由于所有EJB實(shí)例間不存在區(qū)別,因此完全不同的客戶(hù)可以調(diào)用相同的業(yè)務(wù)方法。在業(yè)務(wù)方法調(diào)用結(jié)束后,各個(gè)無(wú)狀態(tài)會(huì)話Bean實(shí)例依然是相同的,因此,EJB容器能夠針對(duì)客戶(hù)請(qǐng)求,在每個(gè)方法級(jí)將各個(gè)EJB實(shí)例指定給客戶(hù),即使同一客戶(hù)對(duì)同一業(yè)務(wù)方法的多次調(diào)用,都可以由不同的EJB實(shí)例響應(yīng)它,當(dāng)然,將EJB實(shí)例指定給客戶(hù)的具體實(shí)現(xiàn)策略取決于具體的EJB容器。
          7、最后,容器調(diào)用ejbRemove()方法。

          posted @ 2009-11-02 16:35 王永慶 閱讀(195) | 評(píng)論 (0)編輯 收藏
              剛洗了個(gè)澡,看了下時(shí)間,還不算太晚,23點(diǎn)剛過(guò)一點(diǎn),突然想寫(xiě)博客了,有點(diǎn)神經(jīng)質(zhì)了,o(∩_∩)o...
              眼看就要辭職了,離開(kāi)現(xiàn)在的公司了,馬上就要離開(kāi)旁邊的那個(gè)她了,不知道離開(kāi)之后,她還能不能想起旁邊的我,我們雖然不是一類(lèi)人,我這么感覺(jué),不知道離開(kāi)之后,她的工作還順利不。我還在公司的時(shí)候,每當(dāng)她遇到問(wèn)題,還有耐心的我?guī)退鉀Q,遇到問(wèn)題的時(shí)候應(yīng)該讓她自己去解決,感覺(jué)她還是比較獨(dú)立的,可能解決問(wèn)題費(fèi)勁一點(diǎn)。她不適合做程序員,現(xiàn)在太多人不適合做程序員了,現(xiàn)在的程序員已經(jīng)不是程序員了。
              認(rèn)識(shí)她是在2個(gè)月前,那時(shí)我已經(jīng)打算辭職了,但是還沒(méi)有提出來(lái)。這時(shí)的工作到了關(guān)鍵的時(shí)候,面臨著上線的壓力,公司還在不斷的招人,這時(shí)她進(jìn)入了我們組,第一眼看到她的時(shí)候,沒(méi)什么感覺(jué),咋一看去,很普通的一個(gè)女孩,算不上特別漂亮,但是也有幾分姿色,萬(wàn)沒(méi)有想到就是這么一個(gè)有幾分姿色的女孩對(duì)我有這么大的殺傷力。不知道經(jīng)理怎么分的,讓我去帶她,可能經(jīng)理早就知道我要走。沒(méi)有過(guò)幾天,公司的座位開(kāi)始調(diào)整,因?yàn)楝F(xiàn)在組員太分散了,比較難溝通,所以又重新排列了座位,不知道怎么回事,把我分到了她的旁邊,也可能比較容易培訓(xùn)吧。教導(dǎo)她的時(shí)候可謂是盡心盡力了,雖然我人比較好,對(duì)任何人的請(qǐng)求來(lái)之不懼,但是不知不覺(jué)中我感覺(jué)對(duì)她的付出超出了我的義務(wù)。開(kāi)始的時(shí)候,感覺(jué)她還真把我當(dāng)了個(gè)哥哥,旁邊的幾個(gè)好兄弟也總是拿我們開(kāi)玩笑,總是管她叫嫂子,他們叫嫂子的時(shí)候,我的心里可緊張,緊張她生氣,緊張她的心情,緊張她...,不過(guò)還好,她的性格很傻很天真的那種,一個(gè)耳朵進(jìn),一個(gè)耳朵出,今天生氣,明天就好的那種,不知道哪一天她真的生氣了,好嚴(yán)肅,:-),一臉的陰霾,呵呵,女人生起氣來(lái)也很可怕,她用她自己獨(dú)特的方式回?fù)袅宋覀儯聊3聊米屛业男牟荒芷届o,不知道從什么時(shí)候起,我的心中有了她的一席之地,一顆被栓著的心真的很痛苦,之后的幾天里,她的臉色依舊嚴(yán)肅著,感覺(jué)和她的距離拉遠(yuǎn)了,之后和她說(shuō)話也都是工作上的多。
              0:00,今天先寫(xiě)到這里吧,明天白天還要繼續(xù)技術(shù)博客呢,晚上繼續(xù)我的那個(gè)她,1個(gè)小時(shí)才寫(xiě)了這么點(diǎn),因?yàn)檎J(rèn)真的回憶了,能讓我回憶的東西真的不多。現(xiàn)在的心中還有這個(gè)結(jié),這個(gè)結(jié)打的好死,費(fèi)了我好多腦細(xì)胞差不多打開(kāi)了。
              脫衣服,準(zhǔn)備睡覺(jué),晚安,我心中的那個(gè)她。

          posted @ 2009-11-02 00:03 王永慶 閱讀(347) | 評(píng)論 (2)編輯 收藏
          分散配置:
          有時(shí)你會(huì)發(fā)現(xiàn)將配置文件分成幾個(gè)分散的配置文件是很有益的。
          將Data Source配置到Bean裝配文件中不是很適合。數(shù)據(jù)庫(kù)細(xì)節(jié)是一個(gè)發(fā)布信息。而B(niǎo)ean裝配文件的目的是定義如何裝配系統(tǒng)的各個(gè)模塊。如果使用ApplicationContext當(dāng)作Spring容器,那么,在Spring中分離屬性配置是很簡(jiǎn)單的。使用Spring的PropertyPlaceholderConfigurer告訴Spring從外部屬性文件裝載一些配置信息。
          <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                  
          <property name="url">
                      
          <value>jdbc:hsqldb:Training</value>
                  
          </property>
                  
          <property name="driverClassName">
                      
          <value>org.hsqldb.jdbcDriver</value>
                  
          </property>
                  
          <property name="username">
                      
          <value>appUser</value>
                  
          </property>
                  
          <property name="password">
                      
          <value>password</value>
                  
          </property>
              
          </bean>
          location屬性告訴Spring從哪里找到屬性文件。location屬性允許你使用單個(gè)配置文件。如果你想將配置信息分散到多個(gè)配置文件中,請(qǐng)使 用PropertyPlaceholderConfigurer的locations屬性設(shè)置文件列表,使用這種方式,可以使用占位符變量代替Bean裝 配文件中的硬編碼配置了。

          <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
                  
          <property name="location">
                      
          <value>jdbc.properties</value>
                  
          </property>
                  
          <property name="locations">
                      
          <list>
                          
          <value>jdbc.properties</value>
                          
          <value>security.properties</value>
                          
          <value>application.properties</value>
                      
          </list>
                  
          </property>
              
          </bean>
              
          <bean id="dataSources" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                  
          <property name="url">
                      
          <value>${database.url}</value>
                  
          </property>
                  
          <property name="driverClassName">
                      
          <value>${database.driver}</value>
                  
          </property>
                  
          <property name="username">
                      
          <value>${database.user}</value>
                  
          </property>
                  
          <property name="password">
                      
          <value>${database.password}</value>
                  
          </property>
              
          </bean>

          定制屬性編輯器:
          java.beans.PropertyEditor接口提供了將字符串值映射成非String類(lèi)型的方法。有一個(gè)好用的這個(gè)接口的實(shí)現(xiàn)-

          java.beans.PropertyEditorSupport,它有2個(gè)方法我們會(huì)感興趣:
          1、getAsText():方法返回一個(gè)表示屬性值的字符串。
          2、setAsText(String value):將傳遞進(jìn)來(lái)的字符串賦給Bean的屬性。

          Spring帶了幾種建立在propertyEditorSupport之上的定制編輯器,包括

          org.springframework.beans.propertyeditors.URLEditor,它是一個(gè)用于將字符串與java.net.URL相互轉(zhuǎn)換的定制編輯器。
          Spring提供的其他定制編輯器包括:
          1、ClassEditor-使用包含全稱(chēng)類(lèi)名的字符串設(shè)置java.lang.Class屬性。
          2、CustormDateEditor-使用某種java.text.DateFormat對(duì)象將一個(gè)字符串設(shè)置給java.util.Date屬性。
          3、FileEditor-使用包含文件路徑的字符串設(shè)置java.io.File屬性。
          4、LocalEditor-使用包含地域信息的字符串設(shè)置java.util.Local屬性。
          5、StringArrayPropertyEditor-將一個(gè)包含逗號(hào)的String轉(zhuǎn)換成String數(shù)組屬性。
          6、StringTrimmerEditor-自動(dòng)修正字符串屬性,可以選擇將空字符串轉(zhuǎn)變?yōu)閚ull.
          <bean id="costomEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
                  
          <property name="customEditors">
                      
          <map>
                          
          <entry key="com.wyq.spring.PhoneNumber">
                              
          <bean id="phoneEditor" class="com.wyq.spring.PhoneEditor"></bean>
                          
          </entry>
                      
          </map>
                  
          </property>
              
          </bean>
          其中的map中的key表示要添加自定義屬性的類(lèi),value表示自定義屬性實(shí)現(xiàn)的類(lèi)。

          package com.wyq.spring;

          import java.beans.PropertyEditorSupport;

          public class PhoneEditor extends PropertyEditorSupport {
              
              
          public void setAsText(String textValue) throws IllegalArgumentException {
                  String stripped 
          = stripNonNumberic(textValue);
                  
                  String areaCode 
          = stripped.substring(0,3);
                  String prefix 
          = stripped.substring(3,6);
                  String number 
          = stripped.substring(6);
                  PhoneNumber phone 
          = new PhoneNumber(areaCode,prefix,number);
                  setValue(phone);
              }
              
          private String stripNonNumberic(String original){
                  StringBuffer allNumberic 
          = new StringBuffer();
                  
          for(int i=0;i<original.length();i++){
                      
          char c = original.charAt(i);
                      
          if(Character.isDigit(c)){
                          allNumberic.append(c);
                      }
                  }
                  
          return allNumberic.toString();
              }
          }


          posted @ 2009-10-31 17:54 王永慶 閱讀(322) | 評(píng)論 (0)編輯 收藏
          為將企業(yè)Bean的中間件服務(wù)需求告知EJB容器,開(kāi)發(fā)者還需生成部署描述符。
          <?xml version="1.0" encoding="UTF-8"?>
          <ejb-jar version="2.1" xmlns="http://java.sun.com/xml/ns/j2ee"
           xmlns:xsi
          ="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation
          ="http://java.sun.com/xml/ns/j2ee
           http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"
          >
          <!-- 
              <ejb-name>:企業(yè)Bean的昵稱(chēng)。在部署描述符的其他地方能夠引用它,供設(shè)置其他參數(shù)使用。
              <home>:Home接口的全限定名。
              <remote>:遠(yuǎn)程接口的全限定名。
              <local-home>:本地Home接口的全限定名。
              <local>:本地接口的全限定名。
              <ejb-class>:企業(yè)Bean類(lèi)的全限定名。
              <session-type>:標(biāo)識(shí)企業(yè)Bean是有狀態(tài)的,還是無(wú)狀態(tài)的。
              <transaction-type>:事務(wù)類(lèi)型。
           
          -->
              
          <enterprise-beans>
                  
          <session>
                      
          <ejb-name>Hello</ejb-name>
                      
          <home>examples.HelloHome</home>
                      
          <remote>examples.Hello</remote>
                      
          <local-home>examples.HelloLocalHome</local-home>
                      
          <local>examples.HelloLocal</local>
                      
          <ejb-class>examples.HelloBean</ejb-class>
                      
          <session-type>Stateless</session-type>
                      
          <transaction-type>Container</transaction-type>
                  
          </session>
              
          </enterprise-beans>
          </ejb-jar>

          Ejb-jar文件:
          HelloWorld EJB組件準(zhǔn)備好了之后只需將他們打包成Ejb-jar文件。手工創(chuàng)建jar文件
          jar cf HelloWorld.jar *

          注意:ejb-jar.xml文件必須放置在META-INF子目錄中。當(dāng)EJB容器初次打開(kāi)Ejb-jar文件時(shí),將在ejb-jar.xml中查找Ejb-jar所包含的EJB組件信息。

          如何調(diào)用EJB組件:
          目前,存在2類(lèi)客戶(hù):
          1、基于Java RMI-IIOP的客戶(hù)。這類(lèi)客戶(hù)使用JNDI,即通過(guò)網(wǎng)絡(luò)查找對(duì)象。另外,它們使用JTA控制事務(wù)。
          2、CORBA客戶(hù)。這類(lèi)客戶(hù)村尋CORBA標(biāo)準(zhǔn)。這對(duì)于使用其他語(yǔ)言訪問(wèn)EJB組件的客戶(hù)而言,意義深遠(yuǎn),CORBA客戶(hù)使用CORBA命名服務(wù),即通過(guò)網(wǎng)絡(luò)查找對(duì)象。
          訪問(wèn)EJB組件的步驟:
          1、查找Home對(duì)象
          2、使用Home對(duì)象創(chuàng)建EJB對(duì)象
          3、調(diào)用EJB對(duì)象的業(yè)務(wù)方法
          4、銷(xiāo)毀EJB對(duì)象

          查找Home對(duì)象:
          開(kāi)發(fā)EJB應(yīng)用的最主要目標(biāo)之一是,應(yīng)用代碼能夠"一次編寫(xiě),到處運(yùn)行".如果將已部署在機(jī)器A上的EJB應(yīng)用遷移到機(jī)器B上,EJB應(yīng)用代碼不需要改動(dòng),因?yàn)镋JB實(shí)現(xiàn)了位置透明性。
          借助于命名和目錄服務(wù)能夠?qū)崿F(xiàn)EJB的位置透明性。命名和目錄服務(wù)是能夠在網(wǎng)絡(luò)中存儲(chǔ)和查找資源的產(chǎn)品。

          在企業(yè)部署場(chǎng)景中,EJB服務(wù)器使用命名服務(wù)存儲(chǔ)位置信息,而這些位置信息是用于標(biāo)識(shí)資源的,其中的資源涉及到EJB Home對(duì)象、企業(yè)Bean環(huán)境屬性、數(shù)據(jù)庫(kù)JDBC驅(qū)動(dòng)、消息服務(wù)驅(qū)動(dòng)和其他資源等。通過(guò)使用命名服務(wù),應(yīng)用代碼不用將具體機(jī)器或資源名硬編碼在代碼中,這就是EJB所具備的位置透明性,它使得代碼具有便攜性。

          為實(shí)現(xiàn)位置透明性,EJB容器需要屏蔽掉Home對(duì)象的具體位置,使得EJB組件的客戶(hù)代碼感知不到其具體位置。客戶(hù)不用將Home對(duì)象宿主的機(jī)器名硬編碼于代碼中。相反,使用JNDI就能夠查找到Home對(duì)象。物理上,Home對(duì)象可以存在于網(wǎng)絡(luò)上的任何地方,比如在運(yùn)行EJB容器的同一進(jìn)程地址空間中,其他機(jī)器上的EJB容器中。

          客戶(hù)為定位Home對(duì)象,它必須提供企業(yè)Bean的Home對(duì)象的JNDI昵稱(chēng)。客戶(hù)使用該昵稱(chēng)標(biāo)識(shí)所需的Home對(duì)象。一旦將EJB組件部署到容器中,容器會(huì)自動(dòng)將HelloHome昵稱(chēng)綁定到Home對(duì)象。因此,在對(duì)已部署EJB組件的物理機(jī)器位置不知情時(shí),開(kāi)發(fā)者能夠在任一機(jī)器上使用該昵稱(chēng)查找到上述Home對(duì)象,借助于JNDI能夠查找到它。JNDI能夠在網(wǎng)絡(luò)上查找命名服務(wù),或在JNDI樹(shù)中查找到Home對(duì)象,當(dāng)然,Home對(duì)象也可能位于客戶(hù)同一進(jìn)程中,最后一旦找到Home對(duì)象,客戶(hù)將獲得對(duì)它的引用。
          package com.wyq.ejb;

          import java.util.Properties;

          import javax.naming.Context;
          import javax.naming.InitialContext;

          /**
           * 客戶(hù)代碼實(shí)例,用于調(diào)用簡(jiǎn)單、無(wú)狀態(tài)會(huì)話Bean中的方法。
           *
           
          */
          public class HelloClient {

              
              
          public static void main(String[] args)throws Exception {
                  
          /*
                   * 設(shè)置屬性,用于JNDI初始化,從命令行讀入屬性。
                   
          */
                  Properties props 
          = System.getProperties();
                  
          /*
                   * 初始上下文是連接到JNDI樹(shù)的入口。
                   * 借助于環(huán)境屬性,能夠完成JNDI驅(qū)動(dòng)、服務(wù)器的網(wǎng)絡(luò)地址等的設(shè)置
                   
          */
                  Context ctx 
          = new InitialContext(props);
                  
          /*
                   * 獲得對(duì)Home對(duì)象的引用。Home對(duì)象是創(chuàng)建EJB對(duì)象的工廠。
                   
          */
                  Object obj 
          = ctx.lookup("HelloHome");
                  
          /*
                   * Home對(duì)象是RMI-IIOP對(duì)象。因此,需要借助于特殊的RMI-IIOP造型操作將它們?cè)煨统蒖MI-IIOP對(duì)象
                   
          */
                  HelloHome home 
          =(HelloHome)javax.rmi.PortableRemoteObject.narrow(obj,HelloHome.class);
                  
          /*
                   * 使用工廠,來(lái)創(chuàng)建Hello EJB對(duì)象。
                   
          */
                  Hello hello 
          = home.create();
                  
          /*
                   * 調(diào)用EJB對(duì)象的hello()方法。它會(huì)將調(diào)用委派給EJB Bean類(lèi)實(shí)例。一旦接收到響應(yīng)結(jié)果,它便會(huì)返回。
                   
          */
                  System.out.println(hello.hello());
                  
          /*
                   * 在使用完EJB對(duì)象后,需要銷(xiāo)毀它。EJB容器負(fù)責(zé)銷(xiāo)毀EJB對(duì)象。
                   
          */
                  hello.remove();

              }

          }

          posted @ 2009-10-31 12:36 王永慶 閱讀(131) | 評(píng)論 (0)編輯 收藏
          為創(chuàng)建和銷(xiāo)毀EJB對(duì)象,開(kāi)發(fā)者需要使用Home接口。Home接口的實(shí)現(xiàn)是Home對(duì)象,而Home對(duì)象由EJB服務(wù)器提供的工具生成。
          package com.wyq.ejb;

          import javax.ejb.EJBHome;
          /**
           * Hello EJB組件的Home接口。它由EJB服務(wù)器提供的工具實(shí)現(xiàn)。Home接口實(shí)現(xiàn)
           * 稱(chēng)之為Home對(duì)象。Home對(duì)象充當(dāng)了創(chuàng)建EJB對(duì)象的工廠。
           * 
           * 在該Home接口中,存在create()方法。它對(duì)應(yīng)于HelloBean中的ejbCreate()方法。
           
          */
          public interface HelloHome extends EJBHome {
              
          /**
               * 創(chuàng)建EJB對(duì)象,
               * 
          @return 新建的EJB對(duì)象。
               
          */
              Hello create() 
          throws java.rmi.RemoteException,javax.ejb.CreateException;
              
          /**
               * 1、為獲得對(duì)EJB對(duì)象的引用,客戶(hù)需要使用create方法。其中,create方法還能夠完成
               * EJB組件的初始化工作。
               * 2、create方法拋出了如下異常:RemoteException和CreateException。由于Home對(duì)象是網(wǎng)絡(luò)
               * 使能的基于RMI-IIOP的遠(yuǎn)程對(duì)象,因此要拋出RemoteException異常。
               
          */
          }

          本地Home接口是Home接口的高性能版本。
          package com.wyq.ejb;

          import javax.ejb.EJBLocalHome;
          /**
           * Hello EJB組件的本地Home接口。它由EJB服務(wù)器提供的工具實(shí)現(xiàn)。
           * 本地Home接口實(shí)現(xiàn)稱(chēng)之為本地Home對(duì)象。本地Home對(duì)象充當(dāng)了創(chuàng)建EJB本地對(duì)象的工廠。
           *
           
          */
          public interface HelloLocalHome extends EJBLocalHome {
              
          /**
               * 創(chuàng)建EJB本地對(duì)象
               * 
          @return 返回新創(chuàng)建的EJB本地對(duì)象。
               
          */
              HelloLocal create()
          throws javax.ejb.CreateException;
          }


          創(chuàng)建企業(yè)Bean類(lèi)
          package com.wyq.ejb;

          import java.rmi.RemoteException;

          import javax.ejb.EJBException;
          import javax.ejb.SessionBean;
          import javax.ejb.SessionContext;
          /**
           * 演示無(wú)狀態(tài)會(huì)話Bean.
           *
           
          */
          public class HelloBean implements SessionBean {
              
          private SessionContext ctx;
              
          //EJB規(guī)范定義的方法
              public void ejbCreate(){
                  System.out.println(
          "ejbCreate()");
              }
              
          public void ejbRemove() throws EJBException, RemoteException {
                  System.out.println(
          "ejbRemove()");
              }
              
          public void ejbActivate() throws EJBException, RemoteException {
                  System.out.println(
          "ejbActivate()");
              }

              
          public void ejbPassivate() throws EJBException, RemoteException {
                  System.out.println(
          "ejbPassivate()");
              }
              
          /**
               * 由于企業(yè)Bean宿主在受管容器中,因此容器能夠在任何時(shí)候調(diào)用企業(yè)Bean的方法。但如果企業(yè)Bean
               * 需要查詢(xún)?nèi)萜鞯漠?dāng)前信息的話,需要為EJB提供何種信息呢?比如在EJB中,組件本身可能需要查詢(xún)當(dāng)前用戶(hù)
               * 的安全性憑證信息。
               * 
               * 容器將這些信息包含在稱(chēng)之為"EJB上下文"的對(duì)象中。EJB上下文對(duì)象是通往EJB容器的關(guān)口。其中,EJB上
               * 下文是容器的組成部分,開(kāi)發(fā)者能夠在企業(yè)Bean中訪問(wèn)到它。因此,在某種程度上,EJB上下文是為企業(yè)Bean
               * 訪問(wèn)容器提供的回調(diào)。該回調(diào)有助于企業(yè)Bean探知其自身的狀態(tài),并修改他們。
               * 
               * EJB上下文對(duì)于會(huì)話Bean、實(shí)體Bean、消息驅(qū)動(dòng)Bean而言很有用。比如會(huì)話Bean含有會(huì)話上下文、實(shí)體Bean
               * 含有實(shí)體上下文、消息驅(qū)動(dòng)Bean含有消息驅(qū)動(dòng)上下文。
               * 依據(jù)EJB類(lèi)型的不同,開(kāi)發(fā)者能夠分別通過(guò)調(diào)用setSessionContext、setEntityContext、setMessageDivenContext
               * 方法設(shè)置EJB上下文信息。
               
          */
              
          public void setSessionContext(SessionContext ctx) throws EJBException,
                      RemoteException {
                  
          this.ctx = ctx;
              }
              
          //業(yè)務(wù)方法
              public String hello(){
                  System.out.println(
          "hello()");
                  
          return "Hello,World!";
              }

          }

          posted @ 2009-10-30 13:01 王永慶 閱讀(161) | 評(píng)論 (0)編輯 收藏
          首先開(kāi)發(fā)遠(yuǎn)程接口,遠(yuǎn)程接口支持EJB組件暴露的所有業(yè)務(wù)方法。
          package com.wyq.ejb;

          import javax.ejb.EJBObject;
          /**
           * Hello EJB組件的遠(yuǎn)程接口
           * 
           * 在客戶(hù)同EJB對(duì)象交互時(shí),需要使用這一接口。容器廠商會(huì)實(shí)現(xiàn)這一接口,而相應(yīng)的實(shí)現(xiàn)對(duì)象
           * 就是EJB對(duì)象。EJB對(duì)象會(huì)將客戶(hù)請(qǐng)求委派給實(shí)際的EJB Bean類(lèi)。
           *
           
          */
          public interface Hello extends EJBObject {
              
          /**
               * 返回歡迎信息給客戶(hù)。
               
          */
              
          public String hello()throws java.rmi.RemoteException;
              
          /**
               * 注意:遠(yuǎn)程接口繼承于javax.ejb.EJBObject.其含義是:容器生成的EJB對(duì)象實(shí)現(xiàn)了遠(yuǎn)程接口(EJBObject)
               * 即javax.ejb.EJBObject接口中定義的各個(gè)方法。其中包括比較不同EJB對(duì)象的方法,刪除EJB對(duì)象的方法等。
               * 僅實(shí)現(xiàn)了單個(gè)業(yè)務(wù)方法,即hello().HelloWorld EJB組件的Bean類(lèi)需要實(shí)現(xiàn)hello方法。另外,由于Hello
               * 接口是RMI-IIOP類(lèi)型的遠(yuǎn)程接口,因此必須拋出遠(yuǎn)程異常。這也是企業(yè)Bean類(lèi)中hello方法簽名同遠(yuǎn)程接口中
               * hello方法簽名的區(qū)別。
               
          */
          }

          為訪問(wèn)EJB組件的業(yè)務(wù)方法,本地客戶(hù)應(yīng)該使用本地接口,而不是遠(yuǎn)程接口。

          package com.wyq.ejb;

          import javax.ejb.EJBLocalObject;
          /**
           * Hello EJB組件的本地接口。
           * 
           * 當(dāng)本地客戶(hù)同EJB本地對(duì)象交互時(shí),需要使用這一接口。容器廠商會(huì)實(shí)現(xiàn)這一接口。
           * 而相應(yīng)的實(shí)現(xiàn)對(duì)象就是EJB本地對(duì)象。EJB本地對(duì)象會(huì)將客戶(hù)請(qǐng)求委派給實(shí)際的EJB Bean類(lèi)。
           *
           
          */
          public interface HelloLocal extends EJBLocalObject {
              
          /**
               * 返回歡迎信息給客戶(hù),本地接口繼承EjbLocalObject接口,并且不需要拋出RemoteException.
               
          */
              
          public String hello();
          }

          posted @ 2009-10-30 13:00 王永慶 閱讀(128) | 評(píng)論 (0)編輯 收藏
              由于EJB對(duì)象可以運(yùn)行在與客戶(hù)不同的機(jī)器上,因此客戶(hù)不能夠直接實(shí)例化EJB對(duì)象。EJB推崇位置透明性,因此從這個(gè)角

          度考慮客戶(hù)不應(yīng)該對(duì)EJB對(duì)象的位置信息進(jìn)行關(guān)注。
              為獲得對(duì)EJB對(duì)象的引用,客戶(hù)代碼需要從EJB對(duì)象工廠中請(qǐng)求EJB對(duì)象。該工廠負(fù)責(zé)實(shí)例化EJB對(duì)象。EJB規(guī)范將這種工廠

          稱(chēng)之為Home對(duì)象。Home對(duì)象的職責(zé)主要有:
          1、創(chuàng)建EJB對(duì)象
          2、查找現(xiàn)有的EJB對(duì)象
          3、刪除EJB對(duì)象
              同EJB對(duì)象一樣,Home對(duì)象專(zhuān)屬于特定的EJB容器。Home對(duì)象含有容器特定的邏輯,如負(fù)載均衡邏輯、借助于圖形化管理

          控制臺(tái)追蹤信息等。與此同時(shí),Home對(duì)象也是EJB容器的組成部分,通過(guò)容器提供的工具能夠自動(dòng)創(chuàng)建它。
              Home對(duì)象是創(chuàng)建EJB對(duì)象的工廠。但是Home對(duì)象是如何實(shí)例化EJB對(duì)象的呢?為創(chuàng)建Home對(duì)象,EJB容器需要掌握這方面的

          信息。通過(guò)指定Home接口給容器即可完成這方面信息的注入。Home接口簡(jiǎn)單的定義了用于創(chuàng)建、銷(xiāo)毀和查找EJB對(duì)象的方法。

          容器的Home對(duì)象實(shí)現(xiàn)了Home接口。
              使用Home接口存在一個(gè)問(wèn)題,即通過(guò)Home接口創(chuàng)建EJB實(shí)例速度很慢,而且,借助于遠(yuǎn)程接口調(diào)用EJB實(shí)例也是如此。當(dāng)

          訪問(wèn)EJB對(duì)象時(shí),通常會(huì)依次觸發(fā)如下內(nèi)容:
          1、客戶(hù)調(diào)用本地存根
          2、存根將參數(shù)壓包成適合網(wǎng)絡(luò)傳輸格式
          3、存根借助于網(wǎng)絡(luò)將參數(shù)傳遞給骨架
          4、骨架將參數(shù)解包成適合Java的格式。
          5、骨架調(diào)用EJB對(duì)象。
          6、EJB對(duì)象獲得所需的中間件服務(wù),如連接池、事務(wù)、安全性和生命周期服務(wù)。
          7、EJB對(duì)象調(diào)用企業(yè)Bean實(shí)例,Bean實(shí)例處理客戶(hù)請(qǐng)求。
          從EJB2.0開(kāi)始,客戶(hù)能夠通過(guò)本地對(duì)象(而不是EJB對(duì)象)快速、高效的訪問(wèn)企業(yè)Bean組件。具體過(guò)程如下:
          1、客戶(hù)訪問(wèn)本地對(duì)象
          2、本地對(duì)象獲得所需的中間件服務(wù)
          3、一旦企業(yè)Bean實(shí)例處理完客戶(hù)請(qǐng)求,則將結(jié)果返回給本地對(duì)象,最終傳回給客戶(hù)。

          EJB對(duì)象指請(qǐng)求攔截器,遠(yuǎn)程接口指供請(qǐng)求攔截器使用的接口,Home對(duì)象指工廠,Home接口指工廠接口。
          本地接口存在的缺點(diǎn):
          1、只在同一進(jìn)程中有效。如在同一應(yīng)用服務(wù)器中存在訪問(wèn)銀行賬號(hào)實(shí)體Bean的銀行出納會(huì)話Bean,如果EJB組件代碼本身依賴(lài)

          于本地接口實(shí)現(xiàn),則不能夠通過(guò)遠(yuǎn)程訪問(wèn)到它。
          2、通過(guò)引用(傳址),而不是傳值來(lái)marshal參數(shù)。

          部署描述符:借助于部署描述符文件,EJB組件能夠聲明其依賴(lài)的中間件服務(wù)。然后,EJB容器將通過(guò)部署描述符了解到組件

          待使用的中間件服務(wù)。

          posted @ 2009-10-29 15:56 王永慶 閱讀(207) | 評(píng)論 (0)編輯 收藏
          構(gòu)造函數(shù)注入:
          Set注入法的缺點(diǎn)是,它無(wú)法清晰的表示出哪些屬性是必須的,哪些是可選的。而構(gòu)造函數(shù)注入法的優(yōu)勢(shì)是通過(guò)構(gòu)造函數(shù)來(lái)強(qiáng)制依賴(lài)關(guān)系。
          使用Set注入時(shí),我們通過(guò)<property>元素來(lái)注入屬性的值。構(gòu)造函數(shù)注入也一樣,只不過(guò)是通過(guò)<bean>元素下的<constructor-arg>元素來(lái)指定實(shí)例化這個(gè)bean的時(shí)候需要傳遞的參數(shù)。constructor-arg沒(méi)有name屬性。

          解決構(gòu)造函數(shù)參數(shù)的不確定性:
          有2種方法可以用來(lái)處理構(gòu)造函數(shù)的不確定性:通過(guò)序號(hào)和類(lèi)型。<constructor-arg>元素有一個(gè)可選的index屬性,可以用它來(lái)指定構(gòu)造函數(shù)的順序。
          <bean id="foo" class="com.springinaction.Foo">
              <constructor-arg index="1">
                  <value>http://www.manning.com</value>
              </constructor>
              <constructor-arg index="0">
                  <value>http://www.springinaction.com</value>
              </constructor>
          </bean>
          另一種方法是使用type屬性。可以通過(guò)type屬性確定參數(shù)的類(lèi)型
          <bean id="foo" class="com.springinaction.Foo">
              <constructor-arg type="java.lang.String">
                  <value>http://www.manning.com</value>
              </constructor>
              <constructor-arg type="java.net.URL">
                  <value>http://www.springinaction.com</value>
              </constructor>
          </bean>

          使用構(gòu)造函數(shù)注入的理由:
          1、構(gòu)造函數(shù)注入強(qiáng)制使用依賴(lài)契約。就是如果沒(méi)有提供所有需要的依賴(lài),一個(gè)Bean就無(wú)法被實(shí)例化。
          2、由于Bean的依賴(lài)都通過(guò)它的構(gòu)造函數(shù)設(shè)置了,所以沒(méi)有必要再寫(xiě)多余的Set方法。
          3、因?yàn)橹荒芡ㄟ^(guò)構(gòu)造函數(shù)設(shè)置類(lèi)的屬性,這樣你有效的保證了屬性的不可變性。
          Set注入的依據(jù):
          1、如果Bean有很多依賴(lài),那么構(gòu)造函數(shù)的參數(shù)列表會(huì)很長(zhǎng)。
          2、構(gòu)造函數(shù)只能通過(guò)參數(shù)的個(gè)數(shù)和類(lèi)型來(lái)區(qū)分。
          3、如果構(gòu)造函數(shù)的參數(shù)中有2個(gè)以上是相同類(lèi)型的,那么很難確定每個(gè)參數(shù)的用途。
          4、構(gòu)造函數(shù)注入不利于自身的繼承。

          自動(dòng)裝配:
          你可以讓Spring自動(dòng)裝配,只要設(shè)置需要自動(dòng)裝配的<bean>中的autowire屬性。
          <bean id="foo" class="com.springinaction.Foo" autowire="autowire type"/>
          byName-視圖在容器中尋找和需要自動(dòng)裝配的屬性名相同的Bean.
          byType-視圖在容器中尋找一個(gè)與需要自動(dòng)配置的屬性類(lèi)型相同的Bean.
          constructor-視圖在容器中查找與需要自動(dòng)裝配的Bean的構(gòu)造參數(shù)一致的一個(gè)或多個(gè)Bean.
          autodetect-首先嘗試使用congstructor來(lái)自動(dòng)裝配,然后使用byType方式。

          使用Spring的特殊Bean
          編寫(xiě)一個(gè)后處理Bean,Spring為你提供了2次機(jī)會(huì),讓你切入到Bean的生命周期中,檢查或者修改它的配置,這叫做后處理,后處理實(shí)在Bean實(shí)例化以及裝配完成之后發(fā)生的。postProcessBeforeInitialization()方法在Bean初始化之前被調(diào)用。postProcessAfterInitialization()方法在初始化之后馬上被調(diào)用。
          package com.wyq.hibernate;


          import java.lang.reflect.Field;

          import org.springframework.beans.BeansException;
          import org.springframework.beans.factory.config.BeanPostProcessor;

          public class Fuddifier implements BeanPostProcessor {
              
          /**
               * postProcessAfterInitialization()方法循環(huán)Bean的所有屬性,尋找java.lang.String類(lèi)型的屬性。對(duì)于每個(gè)String屬性,把它傳遞給
               * fuddify()方法,這個(gè)方法將String將變成嘮叨用語(yǔ)。
               
          */
              
          public Object postProcessAfterInitialization(Object bean, String name)
                      
          throws BeansException {
                  Field[] fields 
          = bean.getClass().getDeclaredFields();
                  
          try{
                      
          for(int i=0;i<fields.length;i++){
                          
          if(fields[i].getType().equals(java.lang.String.class)){
                              fields[i].setAccessible(
          true);
                              String original 
          = (String)fields[i].get(bean);
                              fields[i].set(bean,fuddify(original));
                          }
                      }
                  }
          catch(IllegalAccessException e){
                      e.printStackTrace();
                  }
                  
          return bean;
              }
              
          /**
               * postProcessBeforeInitialization()方法沒(méi)有做任何有意義的工作,它只是簡(jiǎn)單的返回沒(méi)有修改過(guò)的Bean.
               
          */
              
          public Object postProcessBeforeInitialization(Object bean, String name)
                      
          throws BeansException {
                  
          return bean;
              }
              
          private String fuddify(String orig){
                  
          if(orig==null)return orig;
                  
          return orig.replaceAll("(r|l)""w").replaceAll("(R|L)""W");
              }

          }


          注冊(cè)后處理Bean:如果你的應(yīng)用系統(tǒng)運(yùn)行在Bean工廠中,你需要調(diào)用工廠的addBeanPostProcessor()方法來(lái)注冊(cè)BeanPostProcessor.
          BeanPostProcessor fuddifier = new Fuddifier();
          factory.addBeanPostProcessor(fuddifier);
          如果你是使用應(yīng)用上下文,你只需要像注冊(cè)其他Bean那樣注冊(cè)后處理Bean.



          posted @ 2009-10-29 14:59 王永慶 閱讀(262) | 評(píng)論 (0)編輯 收藏
              傳統(tǒng)建立應(yīng)用系統(tǒng)對(duì)象之間關(guān)聯(lián)關(guān)系的方法會(huì)導(dǎo)致復(fù)雜的代碼,使它們很難被服用,很難做單元測(cè)試。在Spring中,組件無(wú)需自己負(fù)責(zé)與其他組件的關(guān)聯(lián)。取而代之的是,容器負(fù)責(zé)把協(xié)作左鍵的引用給予各個(gè)組件。創(chuàng)建系統(tǒng)組件之間協(xié)作關(guān)系的這個(gè)動(dòng)作叫做裝配。
              容器是Spring框架的核心。Spring容器使用IOC管理所有組成應(yīng)用系統(tǒng)的組件。這包括在協(xié)作組件之間建立關(guān)聯(lián)。Spring實(shí)際上有2種不同的容器:Bean工廠(org.springframewor.bens.factory.BeanFactory接口定義)是最簡(jiǎn)單的容器,提供了基礎(chǔ)的依賴(lài)注入支持。應(yīng)用上下文(由org.springframework.contextApplicationContext接口定義)建立在Bean工廠基礎(chǔ)之上,提供了系統(tǒng)架構(gòu)服務(wù)。
              (1)、BeanFactory這個(gè)類(lèi)負(fù)責(zé)創(chuàng)建和分發(fā)Bean.由于Bean工廠知道應(yīng)用系統(tǒng)中的很多對(duì)象,所以它可以在實(shí)例化這些對(duì)象的時(shí)候,創(chuàng)建協(xié)作對(duì)象間的關(guān)聯(lián)關(guān)系。這樣就把配置的負(fù)擔(dān)從Bean自身以及Bean的調(diào)用者中脫離出來(lái)。在Spring中有幾種BeanFactory的實(shí)現(xiàn)。其中最常使用的是org.springframework.beans.factory.xml.XmlBeanFactory,它根據(jù)XML文件中的定義裝載Bean.
          例如:BeanFactory factory = new XmlBeanFactory(new FileInputStream("beans.xml"));
          這行代碼告訴Bean工廠從XML文件中讀取Bean的定義信息。但是,現(xiàn)在Bean工廠還沒(méi)有實(shí)例化Bean.Bean是被延遲載入到Bean工廠中的,就是說(shuō)Bean工廠會(huì)立即把Bean定義信息載入進(jìn)來(lái),但是Bean只有在被需要的時(shí)候才被實(shí)例化。
                MyBean myBean = (MyBean)factory.getBean("myBean");
          當(dāng)getBean()方法被調(diào)用的時(shí)候,工廠就會(huì)實(shí)例化Bean并且使用依賴(lài)注入開(kāi)始設(shè)置Bean的屬性。
              (2)、ApplicationContext的諸多實(shí)現(xiàn)中,有3個(gè)實(shí)現(xiàn)經(jīng)常用到:
            ClassPathXmlApplicationContext-從類(lèi)路徑中的XML文件載入上下文定義信息,把上下文定義文件當(dāng)成類(lèi)路徑資源。
            FileSystemXmlApplicationContext-從文件系統(tǒng)中的XML文件載入上下文定義信息。
            XmlWebApplicationContext-從web系統(tǒng)中的XML文件載入上下文定義信息。
          例如:ApplicationContext context = new FileSystemXmlApplicationContext("c:/foo.xml");
                ApplicationContext context = new ClassPathXmlApplicationContext("foo.xml");
          FileSystemXmlApplicationContext只能在指定的路徑中尋找foo.xml文件,而ClassPathXmlApplicationContext可以在整個(gè)類(lèi)路徑中尋找foo.xml.
              應(yīng)用上下文與Bean工廠的另一個(gè)重要區(qū)別是關(guān)于單實(shí)例Bean是如何被載入的。Bean工廠延遲載入所有的Bean,知道getBean()方法被調(diào)用時(shí)Bean才被創(chuàng)建。應(yīng)用上下文啟動(dòng)后預(yù)載入所有的單實(shí)例Bean.

              Spring中的Bean缺省情況下是單例模式。在容器分配Bean的時(shí)候,它總是返回同一個(gè)實(shí)例。如果想每次得到不同的實(shí)例你需要將Bean定義為原型模式。定義為原型模式意味著你是定義一個(gè)Bean藍(lán)圖,而不是一個(gè)單一的Bean.<bean>的singleton屬性告訴這個(gè)bean是否是單例的,如果是true表示是單例的,如果是false表示是原型的。

          <bean id="connectionPool" class="com.springinaction.chapter02.MyConnectionPool" init-method="initialize" destroy-method="close"/>

          按這樣配置,MyConnectionPool被實(shí)例化后initialize()方法馬上被調(diào)用,給Bean初始化池的機(jī)會(huì)。在Bean從容器中刪除之前,close()方法將釋放數(shù)據(jù)庫(kù)連接。

          設(shè)值注入:它是一種基于標(biāo)準(zhǔn)命名規(guī)范的設(shè)置Bean屬性的技術(shù)。JavaBean規(guī)范規(guī)定使用對(duì)應(yīng)的set和get方法來(lái)設(shè)置和獲得Bean的屬性值。<property>元素的子元素<value>用來(lái)設(shè)置普通類(lèi)型的屬性,子元素<ref bean="">用來(lái)設(shè)置要關(guān)聯(lián)的Bean.

          內(nèi)部Bean:另一種不常使用的裝配Bean引用的方法是在<property>元素中嵌入一個(gè)<bean>元素。
          <bean id="courseService" class="com.springinaction.service.training.CourseServiceImpl">
              
          <property name="studentService">
                  
          <bean class="com.springinaction.service.training.StudentServiceImpl"/>
              
          </property>
          </bean>

          這種裝配Bean引用的方式的缺點(diǎn)是你無(wú)法在其他地方重用這個(gè)StudentServiceImpl實(shí)例,因?yàn)樗且粋€(gè)專(zhuān)門(mén)的courseServiceBean建立的實(shí)例。

          注入的是對(duì)象集:如果你有一個(gè)屬性是一個(gè)列表或是一個(gè)Bean引用集合,Spring支持多種類(lèi)型的集合作為屬性。
          <list><set><map><props>

          裝配List和數(shù)組:裝配一個(gè)List屬性,List里的元素可以是任何一種元素,包括<value><ref>甚至是其他<list>
          <property name="barList">
              
          <list>
                  
          <value>bar1</value>
                  
          <ref bean="bar2"/>
              
          </list>
          </property>


          裝配Set:和List一樣,Set可以包含任何類(lèi)型的屬性。
          <property name="barSet">
              
          <set>
                  
          <value>bar1</value>
                  
          <ref bean="bar2"/>
              
          </set>
          </property>

          <set>的使用方法和<list>是一樣的。唯一不同的地方是它被裝到什么樣的屬性中。<list>是向java.util.List或數(shù)組里裝配數(shù)據(jù),而<set>是向java.util.Set中裝配數(shù)據(jù)。

          裝配Map:
          <property name="barMap">
              
          <map>
                  
          <entry key="key1">
                      
          <value>bar1</value>
                  
          </entry>
                  
          <entry key="key2">
                      
          <value>bar2</value>
                  
          </entry>
              
          </map>
          </property>

          Map中的<entry>的數(shù)值和<list>以及<set>的一樣,可以是任何有效的屬性元素。重申一邊,包括<value>、<ref>、<list>甚至是另一個(gè)<map>。注意,配置<entry>時(shí),屬性key的值只能是String.這對(duì)于java.util.Map的功能來(lái)說(shuō)有一點(diǎn)限制,java.util.Map是允許任何類(lèi)型的對(duì)象作為主鍵的。

          裝配properties:java.util.Properties集合是最后一個(gè)能在Spring中裝配的集合類(lèi)。使用<props>元素來(lái)裝配它。使用<prop>元素表示每條屬性。
          <property name="barProps">
              
          <props>
                  
          <prop key="key1">bar1</prop>
                  
          <prop key="key2">bar2</prop>
              
          </props>
          </property>


          設(shè)置null
          為了將一個(gè)屬性設(shè)為null,你只要使用<null/>元素就行了。
          例如:
          <property name="foo"><null/><property>



          posted @ 2009-10-29 10:28 王永慶 閱讀(1602) | 評(píng)論 (2)編輯 收藏
          僅列出標(biāo)題
          共7頁(yè): 上一頁(yè) 1 2 3 4 5 6 7 下一頁(yè) 
          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          常用鏈接

          留言簿(1)

          隨筆分類(lèi)

          隨筆檔案

          關(guān)注blogs

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 沐川县| 呼和浩特市| 开平市| 东宁县| 调兵山市| 当阳市| 巴青县| 陇南市| 富锦市| 闽清县| 金湖县| 德州市| 灵寿县| 洛浦县| 武陟县| 林口县| 工布江达县| 峨山| 岳阳市| 灌云县| 措美县| 巨野县| 天峻县| 紫金县| 永登县| 盘山县| 饶平县| 大荔县| 手游| 龙游县| 长宁县| 台江县| 玉门市| 邯郸市| 晋州市| 迭部县| 南郑县| 百色市| 上高县| 兴安盟| 祁连县|