posts - 51, comments - 17, trackbacks - 0, articles - 9
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          引言

            期待已久的EJB3.0規(guī)范在最近發(fā)布了它的初稿。在本文中將對(duì)新的規(guī)范進(jìn)行一個(gè)概要性的介紹,包括新增的元數(shù)據(jù)支持,EJBQL的修改,實(shí)體Bean模型訪問(wèn)bean上下文的新方法和運(yùn)行時(shí)環(huán)境等等。作者還討論了EJB在未來(lái)要作出的調(diào)整以及EJB3.0與其他開(kāi)發(fā)規(guī)范之間的關(guān)系。

            開(kāi)始

            無(wú)論如何由于EJB的復(fù)雜性使之在J2EE架構(gòu)中的表現(xiàn)一直不是很好。EJB大概是J2EE架構(gòu)中唯一一個(gè)沒(méi)有兌現(xiàn)其能夠簡(jiǎn)單開(kāi)發(fā)并提高生產(chǎn)力的組建。 EJB3.0規(guī)范正嘗試在這方面作出努力以減輕其開(kāi)發(fā)的復(fù)雜性。EJB3.0減輕了開(kāi)發(fā)人員進(jìn)行底層開(kāi)發(fā)的工作量,它取消或最小化了很多(以前這些是必須實(shí)現(xiàn))回調(diào)方法的實(shí)現(xiàn),并且降低了實(shí)體Bean及O/R映射模型的復(fù)雜性。

            在本文中,我首先會(huì)介紹EJB3.0中幾個(gè)主要的改變。它對(duì)進(jìn)一步深入了解EJB3.0是非常重要的。隨后,我會(huì)從更高的層面來(lái)描述已經(jīng)被提交到EJB3.0規(guī)范中的細(xì)節(jié),并一個(gè)個(gè)的講解新的規(guī)范中的改變:實(shí)體 Bean,O/R映射模型,實(shí)體關(guān)系模型和EJB QL(EJB查詢語(yǔ)言)等等。

            背景

            EJB3.0中兩個(gè)重要的變更分別是:使用了Java5中的程序注釋工具和基于Hibernate的O/R映射模型。

            Java5中的元數(shù)據(jù)工具。

            Java5 (以前叫J2SE1.5或Tiger)中加入了一種新的程序注釋工具。通過(guò)這個(gè)工具你可以自定義注釋標(biāo)記,通過(guò)這些自定義標(biāo)記來(lái)注釋字段、方法、類等等。這些注釋并不會(huì)影響程序的語(yǔ)義,但是可以通過(guò)工具(編譯時(shí)或運(yùn)行時(shí))來(lái)解釋這些標(biāo)記并產(chǎn)生附加的內(nèi)容(比如部署描述文件),或者強(qiáng)制某些必須的運(yùn)行時(shí)行為(比如EJB組件的狀態(tài)特性)。注釋的解析可以通過(guò)源文件的解析(比如編譯器或這IDE工具)或者使用Java5中的APIs反射機(jī)制。注釋只能被定義在源代碼層。由于所有被提交到EJB3.0草案中的注釋標(biāo)記都有一個(gè)運(yùn)行時(shí)的RetentionPolicy,因此會(huì)增加類文件占用的存儲(chǔ)空間,但這卻給容器制造商和工具制造商帶來(lái)了方便。

            Hibernate

            目前Hibernate非常受歡迎,它是開(kāi)發(fā)源代碼的Java O/R映射框架,目的是把開(kāi)發(fā)人員從繁瑣的數(shù)據(jù)持久化編程中解脫出來(lái)。它也有一個(gè)標(biāo)準(zhǔn)的HQL(Hibernate 查詢語(yǔ)言)語(yǔ)言,你可以在新的EJB QL中看到它的影子。Hibernate在處理如數(shù)據(jù)查詢、更新、連接池、事務(wù)處理、實(shí)體關(guān)系處理等方面非常簡(jiǎn)單。

            概覽

            在已經(jīng)提交的EJB3.0規(guī)范中主要涉及兩個(gè)方面的改變:

            1. 一套以注釋為基礎(chǔ)的EJB編程模型,再加上EJB2.1中定義的通過(guò)部署描述符和幾個(gè)接口定義的應(yīng)用程序行為。

            2. 新的實(shí)體Bean持久化模型,EJBQL也有許多重要的改變。

            還有一些有關(guān)上述的提議,比如:一個(gè)新的客戶端編程模型,業(yè)務(wù)接口的使用以及實(shí)體Bean的生命周期。請(qǐng)注意EJB2.1編程模型(包括部署描述符和home/remote接口)仍然是有效的。新的簡(jiǎn)化模型并沒(méi)有完全取代EJB2.1模型。

            EJB注釋

            EJB 規(guī)范組織一個(gè)重要的目標(biāo)是減輕原始代碼的數(shù)量,并且他們?yōu)榇私o出了一個(gè)完美而簡(jiǎn)介的辦法。在EJB3.0的里,任何類型的企業(yè)級(jí)Bean只是一個(gè)加了適當(dāng)注釋的簡(jiǎn)單Java對(duì)象(POJO)。注釋可以用于定義bean的業(yè)務(wù)接口、O/R映射信息、資源引用信息,效果與在EJB2.1中定義部署描述符和接口是一樣的。在EJB3.0中部署描述符不再是必須的了;home接口也沒(méi)有了,你也不必實(shí)現(xiàn)業(yè)務(wù)接口(容器可以為你完成這些事情)。

            比如,你可以使用@Stateless注釋標(biāo)記類把Java類聲明為一個(gè)無(wú)狀態(tài)回話bean。對(duì)于有狀態(tài)回話bean來(lái)說(shuō),@Remove注釋可以用來(lái)標(biāo)記一個(gè)特定的方法,通過(guò)這個(gè)注釋來(lái)說(shuō)明在調(diào)用這個(gè)方法之后bean的實(shí)例將被清除掉。

            為了減少描述組件的說(shuō)明信息,規(guī)范組織還采納了由異常進(jìn)行配置(configuration-by-exception)的手段,意思是你可以為所有的注釋提供一個(gè)明確的缺省值,這樣多數(shù)常規(guī)信息就可以據(jù)此推斷得出。

            新的持久化模型

            新的實(shí)體bean也是一個(gè)加了注釋的簡(jiǎn)單Java對(duì)象(POJO)。一旦它被EntityManager訪問(wèn)它就成為了一個(gè)持久化對(duì)象,并且成為了持久化上下文(context)的一部分。一個(gè)持久化上下文與一個(gè)事務(wù)上下文是松耦合的;嚴(yán)格的講,它隱含的與一個(gè)事務(wù)會(huì)話共存。

            實(shí)體關(guān)系也是通過(guò)注釋來(lái)定義的,O/R映射也是,并提供幾種不同的數(shù)據(jù)庫(kù)規(guī)范操作,在EJB2.1中這些要通過(guò)開(kāi)發(fā)人員自己的設(shè)計(jì)模式或者其它技術(shù)來(lái)完成的(比如,自增長(zhǎng)主鍵策略)。

            深入研究

            現(xiàn)在是時(shí)候詳細(xì)了解EJB3.0草案了。讓我們開(kāi)始探討所有EJB中四種企業(yè)級(jí)bean,并看看他們?cè)谛碌囊?guī)范中是什么樣子。

            無(wú)狀態(tài)回話bean

            在EJB3.0規(guī)范中,寫(xiě)一個(gè)無(wú)狀態(tài)回話bean(SLSB)只需要一個(gè)簡(jiǎn)單的Java文件并在類層加上@Stateless注釋就可以了。這個(gè)bean可以擴(kuò)展javax.ejb.SessionBean接口,但這些不是必須的。

            一個(gè)SLSB不再需要home接口,沒(méi)有哪類EJB再需要它了。Bean類可以實(shí)現(xiàn)業(yè)務(wù)接口也可以不實(shí)現(xiàn)它。如果沒(méi)有實(shí)現(xiàn)任何業(yè)務(wù)接口,業(yè)務(wù)接口會(huì)由任意 public的方法產(chǎn)生。如果只有幾個(gè)業(yè)務(wù)方法會(huì)被暴露在業(yè)務(wù)接口中,這些方法可以使用@BusinessMethod注釋。缺省情況下所有產(chǎn)生的接口都是local(本地)接口,你也可以使用@Remote注釋來(lái)聲明這個(gè)接口為remote(遠(yuǎn)程)接口。

            下面的幾行代碼就可以定義一個(gè)HelloWorldbean了。而在EJB2.1中同樣的bean至少需要兩個(gè)接口,一個(gè)實(shí)現(xiàn)類和幾個(gè)空的實(shí)現(xiàn)方法,再加上部署描述符。

          import javax.ejb.*;

          /**
          * A stateless session bean requesting that a remote business
          * interface be generated for it.
          */
          @Stateless
          @Remote
          public class HelloWorldBean {
          public String sayHello() {
          return "Hello World!!!";
          }
          }

            有狀態(tài)回話bean

            除了幾個(gè)SFSB的特別說(shuō)明之外,有狀態(tài)回話bean(SFSB)和SLSB一樣精簡(jiǎn):

            ·一個(gè)SFSB應(yīng)該有一個(gè)方法來(lái)初始化自己(在EJB2.1中是通過(guò)ejbCreate()來(lái)實(shí)現(xiàn)的)。在EJB3.0的規(guī)范中建議這些初始化操作可以通過(guò)自定義方法完成,并把他們暴露在業(yè)務(wù)接口中。在使用這個(gè)bean之前由客戶端來(lái)調(diào)用相應(yīng)的初始化方法。目前規(guī)范組織就是否提供一個(gè)注釋來(lái)標(biāo)記某個(gè)方法用于初始化還存在爭(zhēng)議。

            ·Bean的提供者可以用@Remove注釋來(lái)標(biāo)記任何SFSB的方法,以說(shuō)明這個(gè)方法被調(diào)用之后bean的實(shí)例將被移除。同樣,規(guī)范組織仍然在討論是否要有一種機(jī)制來(lái)處理這種特殊的情況,即當(dāng)這個(gè)方法出現(xiàn)異常的情況下bean的實(shí)例是否被移除。

            下面是對(duì)以上問(wèn)題我個(gè)人的觀點(diǎn):

            ·是否應(yīng)該有一個(gè)注釋來(lái)標(biāo)明一個(gè)方法進(jìn)行初始化呢?我的觀點(diǎn)是——應(yīng)該有,這樣容器就可以在調(diào)用其他方法之前至少調(diào)用一個(gè)方法來(lái)進(jìn)行初始化。這不僅可以避免不必要的錯(cuò)誤(由于沒(méi)有調(diào)用初始化方法)而且可以使容器更明確的判斷是否可以重用SFSB實(shí)例。我暫且把這個(gè)問(wèn)題放一放,規(guī)范組織只考慮為一個(gè)方法提供一個(gè)注釋來(lái)聲明它是一個(gè)初始化方法。

            ·對(duì)于第二個(gè)問(wèn)題我的觀點(diǎn)也是肯定的。這有利于Bean的提供者合客戶端程序?qū)ζ溥M(jìn)行控制。只有一個(gè)遺留的問(wèn)題:那就是一旦調(diào)用這個(gè)方法失敗,是否能移除這個(gè)bean 的實(shí)例?答案是不能,但是它將會(huì)在回話結(jié)束的時(shí)候被移除。
          消息驅(qū)動(dòng)Bean

            消息驅(qū)動(dòng)Bean是唯一一種必須實(shí)現(xiàn)一個(gè)業(yè)務(wù)接口的Bean。這個(gè)接口指出bean支持的是哪一種消息系統(tǒng)。對(duì)于以JMS為基礎(chǔ)的MDB來(lái)說(shuō),這個(gè)接口是 javax.jms.MessageListener。注意MDB業(yè)務(wù)接口不是一個(gè)真正意義上的業(yè)務(wù)接口,它只是一個(gè)消息接口。

            實(shí)體Bean

            ·實(shí)體Bean使用@Entity注釋來(lái)標(biāo)記,所有實(shí)體bean中的屬性/字段不必使用@Transient注釋來(lái)標(biāo)記。實(shí)體bean的持久化字段可以通過(guò)JavaBean-style機(jī)制或者聲明為public/protected字段來(lái)實(shí)現(xiàn)。

            ·實(shí)體bean可以使用助手類來(lái)描述其狀態(tài),但是這些類的實(shí)例并沒(méi)有持久化唯一性(persistent identity)的特性(即,唯一標(biāo)識(shí)這個(gè)bean的字段等),實(shí)際上這些助手類與他們的實(shí)體bean實(shí)例是緊密結(jié)合的;并且這些對(duì)象還是以非共享方式來(lái)訪問(wèn)實(shí)體對(duì)象的。

            實(shí)體關(guān)聯(lián)

            EJB3.0同時(shí)支持Bean之間雙向的合單向的關(guān)聯(lián),它們可以是一對(duì)一、一對(duì)多、多對(duì)一或者是多對(duì)多的關(guān)聯(lián)。然而雙向關(guān)聯(lián)的兩端還要分為自身端(owning side)和對(duì)方端(inverse side)不同的端。自身端負(fù)責(zé)向數(shù)據(jù)庫(kù)通告關(guān)聯(lián)的變更。對(duì)于多對(duì)多的關(guān)聯(lián)自身端必須明確的聲明。實(shí)際上對(duì)方端通過(guò)isInverse=true進(jìn)行注釋(由此自身端就不必說(shuō)明了而是由另一段推斷出)。看來(lái)上面的描述,規(guī)范組織還能說(shuō)讓EJB變的簡(jiǎn)單了嗎?

            O/R映射

            EJB3.0 中的O/R映射模型也有了重要的改變,它從原來(lái)的abstract-persistence-schema-based變成了現(xiàn)在的Hibernate- inspired模式。盡管目前規(guī)范組織還在就此進(jìn)行討論但是一個(gè)明確的模型將會(huì)出現(xiàn)在下一個(gè)版本的草案中。

            舉例來(lái)說(shuō),O/R映射模型將通過(guò)bean類中的注釋來(lái)聲明。而且此方法還會(huì)指出對(duì)應(yīng)的具體表和字段。O/R映射模型提供了一套自有的SQL;而且除了提供一些基本的SQL外還支持某些高層開(kāi)發(fā)的功能。比如,有一個(gè)通過(guò)@Column注釋聲明的字段columnDefinition,那么可以寫(xiě)這樣的SQL: columnDefinition="BLOB NOT NULL"

            客戶端程序模型

            一個(gè)EJB客戶端可以通過(guò) @Inject注釋以一種“注入”的方式獲得一個(gè)bean的業(yè)務(wù)接口引用。你也可以使用另一個(gè)注釋 @javax.ejb.EJBContext.lookup()來(lái)完成上面的操作,但是規(guī)范中沒(méi)有告訴我們一個(gè)普通的Java客戶端怎樣獲得一個(gè)Bean 的實(shí)例,因?yàn)檫@個(gè)普通的Java客戶端是運(yùn)行在一個(gè)客戶端容器中,它無(wú)法訪問(wèn)@javax.ejb.EJBContex對(duì)象。現(xiàn)在還有另外一種機(jī)制來(lái)完成上面的工作那就是使用一個(gè)超級(jí)上下文環(huán)境對(duì)象:@javax.ejb.Context()。但是規(guī)范中沒(méi)有指出該如何在客戶端中使用這個(gè)對(duì)象。

            EJB QL

            EJB QL可以通過(guò)@NamedQuery來(lái)注釋。這個(gè)注釋有兩個(gè)成員屬性分別是name和queryString.一旦定義了這些屬性,就可以通過(guò) EntityManager.createNamedQuery(name)來(lái)指向這個(gè)查詢。你也可以創(chuàng)建一個(gè)標(biāo)準(zhǔn)的JDBC風(fēng)格的查詢并使用 EntityManager.createQuery(ejbqlString)或EntityManager.createNativeQuery (nativeSqlString)(這個(gè)方法用于執(zhí)行一個(gè)本地查詢)來(lái)執(zhí)行查詢。

            EJB QL有兩個(gè)地方可以定義其參數(shù)。javax.ejb.Query接口提供了定義參數(shù)、指向查詢、更新數(shù)據(jù)等等方法。下面是一個(gè)EJBQL指向查詢的例子:

          .. ..
          @NamedQuery(
          name="findAllCustomersWithName",
          queryString="SELECT c FROM Customer c WHERE c.name LIKE :custName"
          )
          .. ..
          @Inject public EntityManager em;
          customers = em.createNamedQuery("findAllCustomersWithName")
          .setParameter("custName", "Smith")
          .listResults();

            下面列出了一些EJB QL的增強(qiáng)特性:

            ·支持批量更新和刪除。

            ·直接支持內(nèi)連接和外連接。FETCH JOIN運(yùn)行你指出關(guān)聯(lián)的實(shí)體,Order可以指定只查詢某個(gè)字段。

            ·查詢語(yǔ)句可以返回一個(gè)以上的結(jié)果值。實(shí)際上,你可以返回一個(gè)依賴的類比如下面這樣:

          SELECT new CustomerDetails(c.id, c.status, o.count)
          FROM Customer c JOIN c.orders o
          WHERE o.count > 100

            ·支持group by 和having。

            ·支持where子句的嵌套子查詢。

            在提交的EJB3.0草案中,EJB QL與標(biāo)準(zhǔn)SQL非常的接近。實(shí)際上規(guī)范中甚至直接支持本地的SQL(就像我們上面提到的那樣)。這一點(diǎn)對(duì)某些程序員來(lái)說(shuō)也許有些不是很清楚,我們將在下面進(jìn)行更詳細(xì)的講解。

            多樣性

            方法許可(Method permissions)可以通過(guò)@MethodPermissions或@Unchecked注釋來(lái)聲明;同樣的,事務(wù)屬性也可以通過(guò) @TransactionAttribute注釋來(lái)聲明。規(guī)范中仍然保留資源引用和資源環(huán)境引用。這些一樣可以通過(guò)注釋來(lái)聲明,但是有一些細(xì)微的差別。比如,上下文(context)環(huán)境要通過(guò)注入工具控制。容器根據(jù)bean對(duì)外部環(huán)境引用自動(dòng)初始化一個(gè)適當(dāng)?shù)囊呀?jīng)聲明的實(shí)例變量。比如,你可以象下面這樣獲得一個(gè)數(shù)據(jù)源(DataSource):

          @Resource(name="myDataSource") //Type is inferred from variable
          public DataSource customerDB;

            在上面的例子中如果你不指定引用資源的名稱(name)那么其中的customerDB會(huì)被認(rèn)為是默認(rèn)值。當(dāng)所有的引用屬性都可得到時(shí),@Injec注釋就可以這樣寫(xiě):

          @Inject public DataSource customerDB;

            容器負(fù)責(zé)在運(yùn)行時(shí)初始化customerDB數(shù)據(jù)源實(shí)例。部署人員必須在此之前在容器中定義好這些資源屬性。

            更好的消息是:那些以前必須檢測(cè)的異常將一去不復(fù)返。你可以聲明任意的應(yīng)用程序異常,而不必在再拋出或捕獲其他類似CreateException和 FinderException這樣的異常。容器會(huì)拋出封裝在javax.ejb.EJBException中的系統(tǒng)級(jí)異常或者只在必要時(shí)候拋出 IllegalArgumentException或IllegalStateException異常。
           EJB文件處理模式

            在我們結(jié)束本節(jié)之前,讓我的快速的瀏覽一下容器提供商在EJB處理模式方面可能的變更。規(guī)范中對(duì)此并沒(méi)有明確的表態(tài),但我可以想到至少兩種模式。

            ·一種辦法是首先利用EJB文件生成類似于EJB2.1部署模式的文件(包括必要的接口和部署描述符)然后再用類似于EJB2.1的方式來(lái)部署這個(gè)EJB組件。當(dāng)然,這樣產(chǎn)生的部署描述符可能并不標(biāo)準(zhǔn)但是它可以解決同一個(gè)容器對(duì)EJB2.1和EJB3.0兼容的問(wèn)題。

            ·另一種方法是一種類似于JSP托放的部署模式。你可以把一個(gè)EJB文件放到一個(gè)預(yù)先定義的目錄下,然后容器會(huì)識(shí)別這個(gè)EJB并處理它,然后部署并使之可以使用。這種方法可以建立于上面那種方法之上,在支持反復(fù)部署時(shí)有很大的幫助。考慮到部署的簡(jiǎn)單性也是EJB3.0規(guī)范的目的之一,我真誠(chéng)的希望在下一個(gè)草案出來(lái)時(shí)能夠確定一個(gè)模式(至少能有一個(gè)非正式的)。

            你有什么想法

            EJB3.0規(guī)范的制定正在有序的進(jìn)行,為了使 EJB的開(kāi)發(fā)變得更加容易,EJB規(guī)范組織作出的努力是有目共睹的。就像他們說(shuō)的那樣,一切對(duì)會(huì)變得簡(jiǎn)單,但做到這一點(diǎn)并不容易。目前已經(jīng)定義了50個(gè)注釋標(biāo)記(還有幾個(gè)將在下一個(gè)草案中發(fā)布),每一個(gè)都有自己的缺省規(guī)則和其他的操作。當(dāng)然,我真的不希望EJB3.0變成EJB2.1的一個(gè)翻版"EJB 3.0 = EJB 2.1 for dummies"(希望這個(gè)等式不要成立)。最后,我還是忍不住要提一些我自己的觀點(diǎn):

            ·首先,規(guī)范確實(shí)使反復(fù)部署變得容易了,并且有一個(gè)簡(jiǎn)單的模式來(lái)訪問(wèn)運(yùn)行時(shí)環(huán)境。我還是覺(jué)得home接口應(yīng)該放棄。

            ·在早期的EJB規(guī)范中,實(shí)體bean用于映射一個(gè)持久化存儲(chǔ)。理論上(也許只是理論上)可能需要把實(shí)體bean映射到一個(gè)遺留的EIS (enterprise information system)系統(tǒng)中。出于將來(lái)擴(kuò)展的考慮這樣作是有好處的,并且可以使更多的業(yè)務(wù)數(shù)據(jù)模型采用實(shí)體bean。也因此其伴隨的復(fù)雜性使得實(shí)體bean不被看好。在本次提交的草案中,一個(gè)實(shí)體bean只是一個(gè)數(shù)據(jù)庫(kù)的映射。并且是基于非抽象持久化模式和簡(jiǎn)單的數(shù)據(jù)訪問(wèn)模式的更加簡(jiǎn)單開(kāi)發(fā)。

            ·我對(duì)模型變更持保留態(tài)度,我認(rèn)為在EJB中包含SQL腳本片斷并不是個(gè)好注意。一些開(kāi)發(fā)人員完全反對(duì)包含某些“SQL片段(SQLness)”(比如 @Table 和 @Column注釋)。我的觀點(diǎn)是這些SQLness是好的,據(jù)此我們可以清楚的知道我們到底要數(shù)據(jù)庫(kù)作些什么。但是某些SQL段我看來(lái)并不是很好,比如 columnDefinition="BLOB NOT NULL",這使得EJB代碼和SQL之間的耦合太過(guò)緊密了。

            ·盡管對(duì)于本地SQL的支持看似很誘人,其實(shí)在EJB代碼中嵌入SQL是一個(gè)非常糟糕的主意。當(dāng)然,有些辦法可以避免在EJB中硬編碼SQL,但是這應(yīng)該在規(guī)范中說(shuō)明,而不能是某些開(kāi)發(fā)人員自己定義的模式。

            ·假設(shè)@Table注釋只用于類。在運(yùn)行時(shí)通過(guò)@Table注釋的name屬性定義的表名稱將必須對(duì)應(yīng)一個(gè)實(shí)際的數(shù)據(jù)庫(kù)表。規(guī)范對(duì)此應(yīng)該給予清楚的說(shuō)明和一致的模式。

            ·規(guī)范還需要更清楚的說(shuō)明客戶端編程模型,尤其是普通java客戶端。規(guī)范中所有的參考都假設(shè)或者隱含的使用EJB客戶端。而且規(guī)范中對(duì)客戶端的向后兼容方面也沒(méi)有給出明確的說(shuō)法。

            ·Transient注釋?xiě)?yīng)該重新命名以避免和已有的transient關(guān)鍵字發(fā)生沖突。事實(shí)上,在這一點(diǎn)上我們更樂(lè)于稍微的背離一下 configuration-by-exception原則并且定義一個(gè)@Persistent注釋來(lái)明確的定義持久化字段。@Persistent注釋可以僅僅是一個(gè)標(biāo)記注釋或者它可以有幾個(gè)屬性來(lái)關(guān)聯(lián)O/R映射注釋。

            與其他規(guī)范的關(guān)聯(lián)

            目前可能影響到EJB3.0的JSR有JSR175(java語(yǔ)言元數(shù)據(jù)工具)和JSR181(Java Web服務(wù)元數(shù)據(jù))

            JSR175已經(jīng)初步完成并且不會(huì)和EJB3.0有太大的沖突;但是JSR181與EJB3.0有兩個(gè)關(guān)聯(lián)的地方:

            ·Web service接口:EJB規(guī)范將采用一種機(jī)制適應(yīng)JSR181以便可以把一個(gè)bean實(shí)現(xiàn)為一個(gè)Web service并告訴Web service如何被客戶端調(diào)用。

            ·JSR 181計(jì)劃采用不同的機(jī)制來(lái)處理安全問(wèn)題。在早期的規(guī)范中EJB建議使用一個(gè)一致的機(jī)制(MethodPermissions),但是JSR 181計(jì)劃使用一個(gè)稍微不同的方式(SecurityRoles和SecurityIdentity注釋)。同樣的RunAs注釋的定義也存在這些許差別。這一問(wèn)題還在解決中最終會(huì)在J2EE層的規(guī)范中維持其一致性。

            在J2EE 1.5中的一些開(kāi)發(fā)規(guī)范可能與EJB3.0有關(guān)聯(lián)。除了上面說(shuō)到的幾個(gè)關(guān)聯(lián)之外現(xiàn)在沒(méi)有其他的開(kāi)發(fā)規(guī)范與EJB3.0有沖突。

            結(jié)束語(yǔ)

            在使EJB的開(kāi)發(fā)變得簡(jiǎn)單高效之前,我們還有很長(zhǎng)一段路要走。規(guī)范組織在降低EJB的開(kāi)發(fā)難度方面起了個(gè)好頭。O/R映射模型的提議還處在早期階段,規(guī)范組織正在完善它。我希望它不要太復(fù)雜也不要與SQL過(guò)分的耦合。讓我們不要只是停留在期望、希望、思考和請(qǐng)求中:提出你的想法并把你的建議發(fā)送給規(guī)范組織 ejb3-feedback@sun.com。JCP并不是很民主的組織,但是你的建議一定是有價(jià)值的。

          posted @ 2007-03-03 11:12 chenweicai 閱讀(156) | 評(píng)論 (0)編輯 收藏

          1、EJB2.0有哪些內(nèi)容?分別用在什么場(chǎng)合? EJB2.0和EJB1.1的區(qū)別?

            答:規(guī)范內(nèi)容包括Bean提供者,應(yīng)用程序裝配者,EJB容器,EJB配置工具,EJB服務(wù)提供者,系統(tǒng)管理員。這里面,EJB容器是EJB之所以能夠運(yùn)行的核心。EJB容器管理著EJB的創(chuàng)建,撤消,激活,去活,與數(shù)據(jù)庫(kù)的連接等等重要的核心工作。JSP,Servlet,EJB,JNDI,JDBC,JMS.....

            2、EJB與JAVA BEAN的區(qū)別?

            答:Java Bean 是可復(fù)用的組件,對(duì)Java Bean并沒(méi)有嚴(yán)格的規(guī)范,理論上講,任何一個(gè)Java類都可以是一個(gè)Bean。但通常情況下,由于Java Bean是被容器所創(chuàng)建(如Tomcat)的,所以Java Bean應(yīng)具有一個(gè)無(wú)參的構(gòu)造器,另外,通常Java Bean還要實(shí)現(xiàn)Serializable接口用于實(shí)現(xiàn)Bean的持久性。Java Bean實(shí)際上相當(dāng)于微軟COM模型中的本地進(jìn)程內(nèi)COM組件,它是不能被跨進(jìn)程訪問(wèn)的。Enterprise Java Bean 相當(dāng)于DCOM,即分布式組件。它是基于Java的遠(yuǎn)程方法調(diào)用(RMI)技術(shù)的,所以EJB可以被遠(yuǎn)程訪問(wèn)(跨進(jìn)程、跨計(jì)算機(jī))。但EJB必須被布署在諸如Webspere、WebLogic這樣的容器中,EJB客戶從不直接訪問(wèn)真正的EJB組件,而是通過(guò)其容器訪問(wèn)。EJB容器是EJB組件的代理,EJB組件由容器所創(chuàng)建和管理。客戶通過(guò)容器來(lái)訪問(wèn)真正的EJB組件。

            2、EJB是基于哪些技術(shù)實(shí)現(xiàn)的?并說(shuō)出SessionBean和EntityBean的區(qū)別,StatefulBean和StatelessBean的區(qū)別。

            答:EJB包括Session Bean、Entity Bean、Message Driven Bean,基于JNDI、RMI、JAT等技術(shù)實(shí)現(xiàn)。

            SessionBean在J2EE應(yīng)用程序中被用來(lái)完成一些服務(wù)器端的業(yè)務(wù)操作,例如訪問(wèn)數(shù)據(jù)庫(kù)、調(diào)用其他EJB組件。EntityBean被用來(lái)代表應(yīng)用系統(tǒng)中用到的數(shù)據(jù)。

            對(duì)于客戶機(jī),SessionBean是一種非持久性對(duì)象,它實(shí)現(xiàn)某些在服務(wù)器上運(yùn)行的業(yè)務(wù)邏輯。

            對(duì)于客戶機(jī),EntityBean是一種持久性對(duì)象,它代表一個(gè)存儲(chǔ)在持久性存儲(chǔ)器中的實(shí)體的對(duì)象視圖,或是一個(gè)由現(xiàn)有企業(yè)應(yīng)用程序?qū)崿F(xiàn)的實(shí)體。

            Session Bean 還可以再細(xì)分為 Stateful Session Bean 與 Stateless Session Bean ,這兩種的 Session Bean都可以將系統(tǒng)邏輯放在 method之中執(zhí)行,不同的是 Stateful Session Bean 可以記錄呼叫者的狀態(tài),因此通常來(lái)說(shuō),一個(gè)使用者會(huì)有一個(gè)相對(duì)應(yīng)的 Stateful Session Bean 的實(shí)體。Stateless Session Bean 雖然也是邏輯組件,但是他卻不負(fù)責(zé)記錄使用者狀態(tài),也就是說(shuō)當(dāng)使用者呼叫 Stateless Session Bean 的時(shí)候,EJB Container 并不會(huì)找尋特定的 Stateless Session Bean 的實(shí)體來(lái)執(zhí)行這個(gè) method。換言之,很可能數(shù)個(gè)使用者在執(zhí)行某個(gè) Stateless Session Bean 的 methods 時(shí),會(huì)是同一個(gè) Bean 的 Instance 在執(zhí)行。從內(nèi)存方面來(lái)看, Stateful Session Bean 與 Stateless Session Bean 比較, Stateful Session Bean 會(huì)消耗 J2EE Server 較多的內(nèi)存,然而 Stateful Session Bean 的優(yōu)勢(shì)卻在于他可以維持使用者的狀態(tài)。

            3、EJB與JAVA BEAN的區(qū)別?

            答:Java Bean 是可復(fù)用的組件,對(duì)Java Bean并沒(méi)有嚴(yán)格的規(guī)范,理論上講,任何一個(gè)Java類都可以是一個(gè)Bean。但通常情況下,由于Java Bean是被容器所創(chuàng)建(如Tomcat)的,所以Java Bean應(yīng)具有一個(gè)無(wú)參的構(gòu)造器,另外,通常Java Bean還要實(shí)現(xiàn)Serializable接口用于實(shí)現(xiàn)Bean的持久性。Java Bean實(shí)際上相當(dāng)于微軟COM模型中的本地進(jìn)程內(nèi)COM組件,它是不能被跨進(jìn)程訪問(wèn)的。Enterprise Java Bean 相當(dāng)于DCOM,即分布式組件。它是基于Java的遠(yuǎn)程方法調(diào)用(RMI)技術(shù)的,所以EJB可以被遠(yuǎn)程訪問(wèn)(跨進(jìn)程、跨計(jì)算機(jī))。但EJB必須被布署在諸如Webspere、WebLogic這樣的容器中,EJB客戶從不直接訪問(wèn)真正的EJB組件,而是通過(guò)其容器訪問(wèn)。EJB容器是EJB組件的代理,EJB組件由容器所創(chuàng)建和管理。客戶通過(guò)容器來(lái)訪問(wèn)真正的EJB組件。

            EJB包括(SessionBean,EntityBean)說(shuō)出他們的生命周期,及如何管理事務(wù)的?

            SessionBean:Stateless Session Bean 的生命周期是由容器決定的,當(dāng)客戶機(jī)發(fā)出請(qǐng)求要建立一個(gè)Bean的實(shí)例時(shí),EJB容器不一定要?jiǎng)?chuàng)建一個(gè)新的Bean的實(shí)例供客戶機(jī)調(diào)用,而是隨便找一個(gè)現(xiàn)有的實(shí)例提供給客戶機(jī)。當(dāng)客戶機(jī)第一次調(diào)用一個(gè)Stateful Session Bean 時(shí),容器必須立即在服務(wù)器中創(chuàng)建一個(gè)新的Bean實(shí)例,并關(guān)聯(lián)到客戶機(jī)上,以后此客戶機(jī)調(diào)用Stateful Session Bean 的方法時(shí)容器會(huì)把調(diào)用分派到與此客戶機(jī)相關(guān)聯(lián)的Bean實(shí)例。

            EntityBean:Entity Beans能存活相對(duì)較長(zhǎng)的時(shí)間,并且狀態(tài)是持續(xù)的。只要數(shù)據(jù)庫(kù)中的數(shù)據(jù)存在,Entity beans就一直存活。而不是按照應(yīng)用程序或者服務(wù)進(jìn)程來(lái)說(shuō)的。即使EJB容器崩潰了,Entity beans也是存活的。Entity Beans生命周期能夠被容器或者 Beans自己管理。

            EJB通過(guò)以下技術(shù)管理實(shí)務(wù):對(duì)象管理組織(OMG)的對(duì)象實(shí)務(wù)服務(wù)(OTS),Sun Microsystems的Transaction Service(JTS)、Java Transaction API(JTA),開(kāi)發(fā)組(X/Open)的XA接口。

            4、EJB的角色和三個(gè)對(duì)象

            答:一個(gè)完整的基于EJB的分布式計(jì)算結(jié)構(gòu)由六個(gè)角色組成,這六個(gè)角色可以由不同的開(kāi)發(fā)商提供,每個(gè)角色所作的工作必須遵循Sun公司提供的EJB規(guī)范,以保證彼此之間的兼容性。這六個(gè)角色分別是EJB組件開(kāi)發(fā)者(Enterprise Bean Provider) 、應(yīng)用組合者(Application Assembler)、部署者(Deployer)、EJB 服務(wù)器提供者(EJB Server Provider)、EJB 容器提供者(EJB Container Provider)、系統(tǒng)管理員(System Administrator)

            三個(gè)對(duì)象是Remote(Local)接口、Home(LocalHome)接口,Bean類
          5、EJB容器提供的服務(wù)

            答:主要提供聲明周期管理、代碼產(chǎn)生、持續(xù)性管理、安全、事務(wù)管理、鎖和并發(fā)行管理等服務(wù)。

            6、EJB規(guī)范規(guī)定EJB中禁止的操作有哪些?

            答:1.不能操作線程和線程API(線程API指非線程對(duì)象的方法如notify,wait等),2.不能操作awt,3.不能實(shí)現(xiàn)服務(wù)器功能,4.不能對(duì)靜態(tài)屬生存取,5.不能使用IO操作直接存取文件系統(tǒng),6.不能加載本地庫(kù).,7.不能將this作為變量和返回,8.不能循環(huán)調(diào)用。

            7、remote接口和home接口主要作用

            答:remote接口定義了業(yè)務(wù)方法,用于EJB客戶端調(diào)用業(yè)務(wù)方法。

            home接口是EJB工廠用于創(chuàng)建和移除查找EJB實(shí)例

            8、bean 實(shí)例的生命周期

            答:對(duì)于Stateless Session Bean、Entity Bean、Message Driven Bean一般存在緩沖池管理,而對(duì)于Entity Bean和Statefull Session Bean存在Cache管理,通常包含創(chuàng)建實(shí)例,設(shè)置上下文、創(chuàng)建EJB Object(create)、業(yè)務(wù)方法調(diào)用、remove等過(guò)程,對(duì)于存在緩沖池管理的Bean,在create之后實(shí)例并不從內(nèi)存清除,而是采用緩沖池調(diào)度機(jī)制不斷重用實(shí)例,而對(duì)于存在Cache管理的Bean則通過(guò)激活和去激活機(jī)制保持Bean的狀態(tài)并限制內(nèi)存中實(shí)例數(shù)量。

            9、EJB的激活機(jī)制

            答:以Stateful Session Bean 為例:其Cache大小決定了內(nèi)存中可以同時(shí)存在的Bean實(shí)例的數(shù)量,根據(jù)MRU或NRU算法,實(shí)例在激活和去激活狀態(tài)之間遷移,激活機(jī)制是當(dāng)客戶端調(diào)用某個(gè)EJB實(shí)例業(yè)務(wù)方法時(shí),如果對(duì)應(yīng)EJB Object發(fā)現(xiàn)自己沒(méi)有綁定對(duì)應(yīng)的Bean實(shí)例則從其去激活Bean存儲(chǔ)中(通過(guò)序列化機(jī)制存儲(chǔ)實(shí)例)回復(fù)(激活)此實(shí)例。狀態(tài)變遷前會(huì)調(diào)用對(duì)應(yīng)的ejbActive和ejbPassivate方法。

            10、EJB的幾種類型

            答:會(huì)話(Session)Bean ,實(shí)體(Entity)Bean 消息驅(qū)動(dòng)的(Message Driven)Bean

            會(huì)話Bean又可分為有狀態(tài)(Stateful)和無(wú)狀態(tài)(Stateless)兩種

            實(shí)體Bean可分為Bean管理的持續(xù)性(BMP)和容器管理的持續(xù)性(CMP)兩種

            11、客服端調(diào)用EJB對(duì)象的幾個(gè)基本步驟

            答:設(shè)置JNDI服務(wù)工廠以及JNDI服務(wù)地址系統(tǒng)屬性,查找Home接口,從Home接口調(diào)用Create方法創(chuàng)建Remote接口,通過(guò)Remote接口調(diào)用其業(yè)務(wù)方法

          posted @ 2007-03-03 10:37 chenweicai 閱讀(159) | 評(píng)論 (0)編輯 收藏

          JBoss,作為J2EE應(yīng)用服務(wù)器,以其EJB容器卓越的性能、技術(shù)的潮流性、開(kāi)發(fā)部署J2EE應(yīng)用的方便性贏得了很多J2EE開(kāi)發(fā)者的信賴。其中,免安裝、基于JMX構(gòu)架、熱部署(Hot?Deploy)、快速開(kāi)發(fā)EJB應(yīng)用等幾項(xiàng)特征與其他商用服務(wù)器相比,顯得有些得意忘形的樣子。盡管其本身沒(méi)有重大的缺陷,但畢竟是Open?Source的開(kāi)發(fā)模式,文檔很少,因此要很好的掌握、精通開(kāi)發(fā)基于JBoss的應(yīng)用還是顯得有些力不從心。
          本文結(jié)合自己的開(kāi)發(fā)經(jīng)驗(yàn),給出在JBoss?3.2.1下開(kāi)發(fā)J2EE一些相關(guān)的注意事項(xiàng)和規(guī)則。其中,讀者一定要知道JBoss?3.2.1作為JBoss的過(guò)渡產(chǎn)品(與JBoss?3.0.x、JBoss?4.x相比),自然有些東西和JBoss?3.0.x、JBoss?4.x有很大差別。但是,一般情況下,本文介紹的內(nèi)容,大體上都適合JBoss各個(gè)版本。
          下載完JBoss?3.2.1后,解壓到一個(gè)沒(méi)有空格的目錄路徑下面就可以運(yùn)行JBoss,所以很方便,但前提是目標(biāo)機(jī)器安裝了Java?2?Standard?Edition。一切就緒后,開(kāi)始我們的旅程。
          (假設(shè)JBoss?3.2.1安裝在:C:\jboss-3.2.1_tomcat-4.1.24,本使用default配置)
          一,????相關(guān)配置文件的設(shè)置
          為開(kāi)發(fā)J2EE應(yīng)用,操作數(shù)據(jù)庫(kù)成了必不可少的內(nèi)容;調(diào)節(jié)日志輸出的詳細(xì)程度成了調(diào)試J2EE應(yīng)用的關(guān)鍵;EJB應(yīng)用的調(diào)優(yōu)過(guò)程是J2EE應(yīng)用的核心。等等,這些內(nèi)容都是我們需要知道的。

          (1)數(shù)據(jù)源的配置:

          在JBoss?3.2.1中,配置數(shù)據(jù)源的步驟很簡(jiǎn)單,JBoss?3.2.1本身帶了主流數(shù)據(jù)庫(kù)的配置實(shí)例,于目錄下:C:\jboss-3.2.1_tomcat-4.1.24\docs\examples\jca。具體使用那個(gè)配置文件取決于目標(biāo)用戶的數(shù)據(jù)庫(kù)。如果是SQL?Server?2000,則需要使用mssql-ds.xml文件(支持本地事務(wù))或者mssql-xa-ds.xml文件(支持全局事務(wù));如果是Oracle?9i數(shù)據(jù)庫(kù),則需要使用oracle-ds.xml文件或者oracle-xa-ds.xml文件。等等。這里以SQL?Server?2000為例。
          首先將mssql-ds.xml文件拷貝到目錄:C:\jboss-3.2.1_tomcat-4.1.24\server\default\deploy下。然后打開(kāi)文件,并作如下修改:
          <datasources>
          ????<local-tx-datasource>
          ????????<jndi-name>VSSDB</jndi-name>
          ????????<connection-url>jdbc:microsoft:sqlserver://125.16.45.158:1433;DatabaseName=DDD
          </connection-url>
          ????????<driver-class>com.microsoft.jdbc.sqlserver.SQLServerDriver</driver-class>
          ????????<user-name>sa</user-name>
          ????????<password>sa</password>
          ????????<min-pool-size>50</min-pool-size>
          ????????<max-pool-size>200</max-pool-size>
          ????</local-tx-datasource>
          </datasources>
          如果目標(biāo)J2EE應(yīng)用只需要本地事務(wù),則上述過(guò)程已經(jīng)完成了Datasource的配置,同時(shí)這個(gè)配置將用于JDBC以及EJB通過(guò)JNDI使用。如果要實(shí)現(xiàn)EJB使用Datasource,則還需要修改位于目錄:C:\jboss-3.2.1_tomcat-4.1.24\server\default\conf下的standardjbosscmp-jdbc.xml文件。比如,
          <jbosscmp-jdbc>

          ???<defaults>
          ??????<datasource>java:/VSSDB1</datasource>
          ??????<datasource-mapping>MS?SQLSERVER2000</datasource-mapping>

          ??????<create-table>true</create-table>
          ??????<remove-table>false</remove-table>
          ??????<read-only>false</read-only>
          ??????<time-out>300</time-out>
          ??????<pk-constraint>true</pk-constraint>
          ??????<fk-constraint>false</fk-constraint>
          。。。。。。。。
          其中,<datasource>java:/VSSDB</datasource>中的VSSDB就是mssql-ds.xml配置的數(shù)據(jù)源;而“java:/”前綴表明該命名空間只是對(duì)JBoss本身可見(jiàn),即運(yùn)行于JBoss外的應(yīng)用是不能夠使用這里定義的數(shù)據(jù)源,這一點(diǎn)希望讀者注意。
          其次,<datasource-mapping>MS?SQLSERVER2000</datasource-mapping>中的MS?SQLSERVER2000可以在該文件的其他地方找到。(如果是其他數(shù)據(jù)庫(kù),情況都是類似的,希望讀者加以思考!)

          (2)日志的輸出詳細(xì)程度配置:
          ????
          由于JBoss?3.2.1開(kāi)發(fā)采用了Log4j管理其日志信息(嚴(yán)格地講,它擴(kuò)展了Log4j),因此了解Log4j的機(jī)理,有助于理解JBoss?3.2.1管理日志的方式。
          JBoss?3.2.1采用JMX架構(gòu)的同時(shí),且以.xml文件類型為配置文件,因此可以找到位于目錄:C:\jboss-3.2.1_tomcat-4.1.24\server\default\conf下的log4j.xml文件。比如,其中一段配置示例如下:
          ??????<appender?name="CONSOLE"?class="org.apache.log4j.ConsoleAppender">
          ????<param?name="Target"?value="System.out"/>
          ????<param?name="Threshold"?value="INFO"/>

          ????<layout?class="org.apache.log4j.PatternLayout">
          ??????<!--?The?default?pattern:?Date?Priority?[Category]?Message\n?-->
          ??????<param?name="ConversionPattern"?value="%d{ABSOLUTE}?%-5p?[%c{1}]?%m%n"/>
          ????</layout>
          ??</appender>
          比如,為了調(diào)節(jié)JBoss?3.2.1控制臺(tái)日志輸出的詳細(xì)程度(調(diào)整為DEBUG級(jí)別),我們需要修改value=”INFO”,將INFO改為DEBUG。
          如果目標(biāo)讀者在開(kāi)發(fā)Entity?Beans,可以調(diào)節(jié)位于與log4j.xml文件同一目錄下的standardjboss.xml文件(該文件主要是提供修改EJB相關(guān)的調(diào)試、運(yùn)行、調(diào)優(yōu)、部署參數(shù))。如果目標(biāo)讀者Entity?Beans采用的<container-name>為Standard?CMP?2.x?EntityBean,則將其中的<call-logging>屬性的取值改為true。
          <container-configuration>
          ????????<container-name>Standard?CMP?2.x?EntityBean</container-name>
          ????????<call-logging>false</call-logging>
          <invoker-proxy-binding-name>entity-rmi-invoker</invoker-proxy-binding-name>
          ????????<sync-on-commit-only>false</sync-on-commit-only>
          。。。。。。。。。
          完成上述兩步后,讀者在調(diào)試Entity?Beans時(shí)通過(guò)控制臺(tái),可以看到Entity?Beans發(fā)出的JDBC調(diào)用細(xì)節(jié)。

          (3)Tomcat容器相關(guān)參數(shù)的配置:

          如果目標(biāo)讀者使用JBoss?3.2.1與Tomcat?4.1.24的集成版本,則可以通過(guò)調(diào)節(jié)分別位于目錄:C:\jboss-3.2.1_tomcat-4.1.24\server\default\deploy\jbossweb-tomcat.sar下的web.xml和目錄:C:\jboss-3.2.1_tomcat-4.1.24\server\default\deploy\jbossweb-tomcat.sar\META-INF下的jboss-service.xml文件來(lái)達(dá)到目標(biāo)讀者特定需求。
          比如,如果想將HTTP服務(wù)端口改為80,則可以修改jboss-service.xml文件;如果想使目標(biāo)J2EE應(yīng)用處理更多的文件類型,可以修改web.xml文件。

          (4)相關(guān)類庫(kù)的放置:

          如果您的應(yīng)用涉及到第三方類庫(kù),比如JDBC?Driver,則可以將這些JDBC?Driver存放到目錄下:C:\jboss-3.2.1_tomcat-4.1.24\server\default\lib。注意,不是目錄:C:\jboss-3.2.1_tomcat-4.1.24\lib下。
          如果是與目標(biāo)J2EE應(yīng)用相關(guān),則可以存放到目標(biāo).war(或者.ear)里面,或者xxx.war目錄中的WEB-INFO\lib下。無(wú)論那種情形,都需要遵循J2EE規(guī)范。

          當(dāng)然,JBoss?3.2.1的配置文件有很多,比如提供郵件服務(wù)的mail-service.xml文件,等等。在這里只是給讀者一些信息,如果您有相關(guān)問(wèn)題,都可以試著本文介紹的一些內(nèi)容解決您的問(wèn)題。謝謝。

          二,開(kāi)發(fā)EJB應(yīng)用
          如果開(kāi)發(fā)EJB應(yīng)用,建議采用JBoss作為開(kāi)發(fā)服務(wù)器,因?yàn)殚_(kāi)發(fā)、調(diào)試、部署速度快。如果采用其他商用服務(wù)器,由于實(shí)現(xiàn)機(jī)理的不同,其編譯的速度很慢。
          如果采用Entity?Beans技術(shù),則您需要知道這么幾點(diǎn)。第一,您目標(biāo)系統(tǒng)的數(shù)據(jù)源有多少個(gè)操作入口,即是否存在Entity?Beans之外的方式來(lái)操作數(shù)據(jù)庫(kù)。如果有,則需要調(diào)節(jié)相應(yīng)<container-name>的<commit-option>提交策略以及<locking-policy>策略。
          比如,JBoss?3.2.1采用的<commit-option>方式有4種:A、B、C、D。當(dāng)然,如果除了Entity?Beans訪問(wèn)數(shù)據(jù)庫(kù)外,別無(wú)它出,采用A是很理智的。如果有,則需要取決于具體的情況使用<commit-option>方式。同時(shí),<commit-option>方式的選擇與<locking-policy>策略有關(guān)系。
          能夠采用<read-only>的Entity?Beans或Entity?Beans?Methods,則盡量采用,這樣會(huì)減少或消除死鎖發(fā)生的可能性。
          盡量采用1:n的關(guān)系來(lái)操作n方的數(shù)據(jù)表結(jié)構(gòu),這樣能夠提高EJB?Container的效率。

          待續(xù)。。。。。。

          posted @ 2007-03-01 10:47 chenweicai 閱讀(173) | 評(píng)論 (0)編輯 收藏

          ? bin???????????????????啟動(dòng)和關(guān)閉JBoss的腳本
          ??client????????????????客戶端與JBoss通信所需的的Java庫(kù)(JARs)
          ??docs??????????????????配置的樣本文件(數(shù)據(jù)庫(kù)配置等)
          ??doc/dtd???????????????在JBoss中使用的各種XML文件的DTD。
          ??lib???????????????????一些JAR,JBoss啟動(dòng)時(shí)加載,且被所有JBoss配置共享。(不要把你的庫(kù)放在這里)
          ??server????????????????各種JBoss配置。每個(gè)配置必須放在不同的子目錄。子目錄的名字表示配置的名字。JBoss包含3個(gè)默認(rèn)的配置:minimial,default和all。
          ??server/all????????????JBoss的完全配置,啟動(dòng)所有服務(wù),包括集群和IIOP
          ??server/default????????JBoss的默認(rèn)配置。在沒(méi)有在JBoss命令航中指定配置名稱時(shí)使用。
          ??server/default/conf???JBoss的配置文件。
          ??server/default/data???JBoss的數(shù)據(jù)庫(kù)文件。比如,嵌入的數(shù)據(jù)庫(kù),或者JBossMQ。
          ??server/default/deploy?JBoss的熱部署目錄。放到這里的任何文件或目錄會(huì)被JBoss自動(dòng)部署EJB、WAR、EAR,甚至服務(wù)。
          ??server/default/lib????一些JAR,JBoss在啟動(dòng)特定配置時(shí)加載他們。?(all和minimial配置也包含這個(gè)和下面兩個(gè)目錄。)
          ??server/default/log????JBoss的日志文件。
          ??server/default/tmp????JBoss的臨時(shí)文件。

          啟動(dòng)時(shí)可用-c參數(shù)指定要啟動(dòng)的配置:run.bat?-c?config-name

          posted @ 2007-02-28 12:49 chenweicai 閱讀(219) | 評(píng)論 (0)編輯 收藏

               摘要: JBoss3.0 下配置和部署 EJB 簡(jiǎn)介 1.JBoss簡(jiǎn)介 JBoss 是一個(gè)運(yùn)行 EJB 的 J2EE 應(yīng)用服務(wù)器。它是開(kāi)放源代碼...  閱讀全文

          posted @ 2007-02-28 10:59 chenweicai 閱讀(410) | 評(píng)論 (0)編輯 收藏

          三個(gè)基本class
          EJB最少也需要三個(gè)class, remote interface, home interface, and bean implementation(bean行為).

          1. remote interface 用來(lái)揭示EJB對(duì)外的一些方法.在這個(gè)例子中,the remote interface 就是org.jboss.docs.interest.Interest.

          ackage org.jboss.docs.interest;

          import javax.ejb.EJBObject;
          import java.rmi.RemoteException;

          /**
          This interface defines the `Remote' interface for the `Interest' EJB. Its
          single method is the only method exposed to the outside world. The class
          InterestBean implements the method.
          */
          public interface Interest extends EJBObject
          {
            public double calculateCompoundInterest(double principle,
                double rate, double periods) throws RemoteException;
          }

          ?

          2.home interface 是用來(lái)規(guī)定怎樣創(chuàng)建一個(gè)實(shí)現(xiàn)remote interface的bean. 在本例中home interface 是 org.jboss.docs.InterestHome.

          package org.jboss.docs.interest;

          import java.io.Serializable;
          import java.rmi.RemoteException;
          import javax.ejb.CreateException;
          import javax.ejb.EJBHome;

          /**
          This interface defines the `home' interface for the `Interest' EJB.
          */
          public interface InterestHome extends EJBHome
          {
          /**
          Creates an instance of the `InterestBean' class on the server, and returns a
          remote reference to an Interest interface on the client.
          */
            Interest create() throws RemoteException, CreateException;
          }


          3.bean implementation 是提供方法的實(shí)現(xiàn),這些方法在上述兩種interface中都有規(guī)定了,在本例中是兩個(gè)方法: calculateCompoundInterest和create().

          這個(gè)bean implementation 是 org.jboss.docs.interest.InterestBean.

          package org.jboss.docs.interest;

          import java.rmi.RemoteException;
          import javax.ejb.SessionBean;
          import javax.ejb.SessionContext;

          /**
          This class contains the implementation for the `calculateCompoundInterest'
          method exposed by this Bean. It includes empty method bodies for the methods
          prescribe by the SessionBean interface; these don't need to do anything in this
          simple example.
          */
          public class InterestBean implements SessionBean
          {
            
            public double calculateCompoundInterest(double principle,
              double rate, double periods)
            {
              System.out.println("Someone called `calculateCompoundInterest!'");
              return principle * Math.pow(1+rate, periods) - principle;
            }

            /** Empty method body
            */
            public void ejbCreate()
            {}

            /** Every ejbCreate() method ALWAYS needs a corresponding
            ejbPostCreate() method with exactly the same parameter types.
            */
            public void ejbPostCreate()
            {}

             /** Empty method body
            */
            public void ejbRemove()
            {}
            /** Empty method body
            */
            public void ejbActivate()
            {}

            /** Empty method body
            */
            public void ejbPassivate()
            {}
            /** Empty method body
            */
            public void setSessionContext(SessionContext sc)
            {}
          }


          ?

          這些classes必須打包進(jìn)一個(gè)JAR文件中,JAR文件中包含了目錄結(jié)構(gòu)和包的層次.在本例中,這些classes是在包org.jboss.docs.interest, 這樣他們需要在目錄org/jboss/docs/interest/ 下.

          部署發(fā)布描述器ejb-jar.xml和jboss.xml
          在JAR文檔創(chuàng)建之前,還需要一個(gè)叫META-INF的目錄,這是存放部署發(fā)布描述器的(一般叫ejb-jar.xml).大部分商用EJB Server提供圖形化工具來(lái)編輯這個(gè) 描述器.在JBoss中需要手工:

          <?xml version="1.0" encoding="UTF-8"?>

          <ejb-jar>
            <description>JBoss Interest Sample Application</description>
            <display-name>Interest EJB</display-name>
            <enterprise-beans>
            <session>
              <ejb-name>Interest</ejb-name>

                <!-- home interface -->
                <home>org.jboss.docs.interest.InterestHome</home>

                <!-- remote interface -->
                <remote>org.jboss.docs.interest.Interest</remote>

                <!-- bean implementation -->
                <ejb-class>org.jboss.docs.interest.InterestBean</ejb-class>

                <!--bean 的類型 這里是Stateless -->
                <session-type>Stateless</session-type>
                <transaction-type>Bean</transaction-type>
            </session>
            </enterprise-beans>
          </ejb-jar>

          在本例中,一個(gè)包中只有一個(gè)EJB 這樣就不用描述多個(gè)EJB之間是怎樣交互的.

          盡管對(duì)于所有的EJB服務(wù)器,ejb-jar.xml部署描述器的格式是一樣的(更多精確的定義可以從sun得到DTD).它并沒(méi)有規(guī)定所有的必須的信息,比如如何將EJB-NAME和JNDI naming service聯(lián)系起來(lái).

          缺省情況下,JNDI name將使用在ejb-jar.xml中<ejb-name>XXX</ejb-name>中的XXX來(lái)使用EJB的home interface.

          但是如果有多個(gè)EJB,在ejb-jar.xml中,在<ejb-name>XXX</ejb-name>中XXX就不能用同一個(gè)名字了,一般格式是"[application name]/[bean name]".

          那么如果再按照缺省情況,JNDI name就可能找不到你的應(yīng)用程序的入口了,因此我們要特別規(guī)定一下.這就需要在jboss.xml中規(guī)定:

          <?xml version="1.0" encoding="UTF-8"?>
          <jboss>
            <enterprise-beans>
              <session>
                <ejb-name>Interest</ejb-name>
                <jndi-name>interest/Interest</jndi-name>
              </session>
            </enterprise-beans>
          </jboss>

          這樣,你所有叫Interest文件都被梆定到JNDI name:interest/Interest下面

          jndi.properties
          雖然有了上面你的應(yīng)用程序和JNDI name的梆定,但是一旦部署發(fā)布到JBoss服務(wù)器上,你還需要一個(gè)jndi.properties文件,以告訴調(diào)用你程序的客戶端請(qǐng)求到哪里去初始化JNDI naming service.

          ?

          java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
          java.naming.provider.url=localhost:1099
          java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

          ?

          在本例中,客戶端請(qǐng)求將尋找Interest 這個(gè)bean, 然后得到這個(gè)bean的home interface. home interface是用來(lái)得到這個(gè)bean的remote interface.最后,客戶端請(qǐng)求將通過(guò)remote interface來(lái)使用由EJB提供的功能.

          posted @ 2007-02-27 22:51 chenweicai 閱讀(388) | 評(píng)論 (0)編輯 收藏

          ??JBoss是一個(gè)開(kāi)放源碼的EJB服務(wù)器,它與其它服務(wù)器整合后可以提供一個(gè)完整的J2EE平臺(tái)。本文介紹如何在Linux環(huán)境下安裝和配置JBoss,以及如何在JBoss平臺(tái)上實(shí)現(xiàn)EJB的開(kāi)發(fā)和部署。

          作為J2EE架構(gòu)中最重要的構(gòu)件,EJB是實(shí)現(xiàn)服務(wù)器端分布式計(jì)算的核心。EBJ服務(wù)器是EJB的容器,它控制著EJB的運(yùn)行,并為其提供事務(wù)處理、數(shù)據(jù)庫(kù)訪問(wèn)、安全控制等一系列系統(tǒng)級(jí)的服務(wù)

          EJB服務(wù)器是J2EE應(yīng)用服務(wù)器的一個(gè)重要組成部分。Sun公司的J2EE SDK、IBM公司的WebSphere,以及BEA公司的WebLogic等J2EE實(shí)現(xiàn)都內(nèi)嵌了EJB服務(wù)器。雖然JBoss目前還不是一個(gè)完整的J2EE應(yīng)用服務(wù)器,但它卻是一個(gè)完整的EJB服務(wù)器,在與Tomcat、Jetty等Web服務(wù)器整合后,能夠提供一個(gè)完整的J2EE平臺(tái)。

          JBoss最大的優(yōu)點(diǎn)在于它是源代碼開(kāi)放的自由軟件,并完全遵循J2EE規(guī)范。由于JBoss強(qiáng)大的功能和優(yōu)異的性能,以及與Linux等GNU項(xiàng)目的結(jié)合,目前已經(jīng)成為J2EE服務(wù)器端企業(yè)級(jí)應(yīng)用的一股強(qiáng)大力量。

          安裝JBoss


          JBoss的安裝和配置相對(duì)比較簡(jiǎn)單。首先到http://www.jboss.org上下載JBoss軟件包。目前JBoss的最高版本為3.0,建議下載相對(duì)穩(wěn)定的JBoss2.4.4和Tomcat3.2.3集成的二進(jìn)制軟件包,這樣就避免了單個(gè)軟件包下載后JBoss和Tomcat之間的配置問(wèn)題。

          下載的軟件包解壓縮到/usr目錄后,將生成/usr/JBoss-2.4.4_Tomcat-3.2.3這目錄。為方便今后的使用,把該目錄更名為/usr/jb_tom。在/usr/jb_tom目錄下可以找到/usr/jb_tom/jboss和/usr/jb_tom/tomcat兩個(gè)子目錄,它們分別為JBoss和Tomcat的根目錄。

          在正式啟動(dòng)JBoss之前,應(yīng)該先安裝好JDK(建議安裝JDK 1.3以上的版本),并將環(huán)境變量ClassPath設(shè)置好。位于/usr/jb_tom/jboss/bin目錄下的run_withtomcat.sh文件是JBoss和Tomcat的啟動(dòng)腳本,按照J(rèn)Boss和Tomcat的默認(rèn)配置,運(yùn)行該腳本后將分別在8080和8083端口啟動(dòng)JBoss和Tomcat的HTTP服務(wù)。如果一切正常,此時(shí)在瀏覽器中輸入http://localhost:8080將出現(xiàn)Tomcat的首頁(yè),而輸入http://localhost:8080則出現(xiàn)無(wú)錯(cuò)誤的空白頁(yè)面。


          創(chuàng)建EJB


          下面以一個(gè)簡(jiǎn)單的無(wú)狀態(tài)會(huì)話Bean為例,講述如何為JBoss平臺(tái)編寫(xiě)EJB。按照EJB規(guī)范,一個(gè)EJB中至少應(yīng)該包含如下三個(gè)類的實(shí)現(xiàn):

          ◆遠(yuǎn)程接口

          遠(yuǎn)程接口暴露了整個(gè)EJB對(duì)外界的接口,在本例中遠(yuǎn)程接口封裝在greet.Greet類中。

          ◆本地接口

          本地接口描述了創(chuàng)建、管理和銷(xiāo)毀EJB時(shí)的行為,在本例中本地接口封裝在greet.GreetHome類中。

          ◆Bean類

          Bean類實(shí)現(xiàn)了遠(yuǎn)程接口中定義的所有方法,在本例中Bean類封裝在greet.GreatBean類中。

          EJB在發(fā)布時(shí)是以一個(gè)JAR包的形式提供的。EJB服務(wù)器要求該JAR包中必須包含所有的類文件和相應(yīng)的部署文件,并且要按照EJB開(kāi)發(fā)時(shí)的目錄結(jié)構(gòu)進(jìn)行組織。在我們的例子中,所有的類文件都位于greet目錄下,部署文件則位于META-INF目錄下,相應(yīng)的目錄結(jié)構(gòu)為:

          greet
            +-- Greet.java
            +-- GreetHome.java
            +-- GreetBean.java
          META-INF
            +-- ejb-jar.xml
            +-- jboss.xml


          1.定義遠(yuǎn)程接口

          EJB向外界暴露的接口都在遠(yuǎn)程接口中進(jìn)行定義,本例中的EJB只向外界提供了一個(gè)接口為calculateMagic,相應(yīng)的源文件為Greet.java,代碼如下:

          package greet;
          import javax.ejb.EJBObject;
          import java.rmi.RemoteException;
          /**
           * 這個(gè)接口為‘Greet’定義了遠(yuǎn)程接口
          public interface Greet extends EJBObject 
          {
              public double calculateMagic(double seed) throws RemoteException;
          }


          2.定義本地接口

          EJB的本地接口對(duì)創(chuàng)建、管理和銷(xiāo)毀EJB的行為進(jìn)行了描述,本地接口至少應(yīng)該提供create()方法,以便對(duì)EJB創(chuàng)建時(shí)的行為進(jìn)行相應(yīng)的描述。例子中本地接口對(duì)應(yīng)的源文件為GreetHome.java,代碼如下:

          package greet;
          import java.io.Serializable;
          import java.rmi.RemoteException;
          import javax.ejb.CreateException;
          import javax.ejb.EJBHome;
          public interface GreetHome extends EJBHome 
          {
           Greet create() throws RemoteException, CreateException;
          }


          3. 實(shí)現(xiàn)Bean類

          EJB真正完成的工作是在Bean類中實(shí)現(xiàn)的,Bean類必須為遠(yuǎn)程接口中定義的所有方法提供相應(yīng)的實(shí)現(xiàn)。本例中的Bean類對(duì)應(yīng)的源文件為GreetBean.java:

          package greet;
          import java.rmi.RemoteException; 
          import javax.ejb.SessionBean;
          import javax.ejb.SessionContext;
          public class GreetBean implements SessionBean 
          {
           public double calculateMagic(double seed) {
            System.out.println ("Someone called `calculateMagic!'");
          return seed * Math.random();
           }
           public GreetBean() {}
          public void ejbCreate() {
           System.out.println("Create Greet EJB.");
          }
          public void ejbRemove() {
           System.out.println("Remove Greet EJB.");
          }
          public void ejbActivate() {
           System.out.println("Activate Greet EJB");
          }
           public void ejbPassivate() {
            System.out.println("Passivate Greet EJB");
           }
          /**
          * Set context for `Greet' EJB
          */
           public void setSessionContext(SessionContext sc) {
            System.out.println("Set context for Greet EJB");
           }
          }


          在給出EJB的接口定義并提供了Bean類的具體實(shí)現(xiàn)后,用下面的命令對(duì)這些.java文件進(jìn)行編譯,生成相應(yīng)的.class文件:

          javac *.java -classpath \
          /usr/jb_tom/jboss/lib/ext/jboss-j2ee.jar:.


          ?

          部署描述符



          根據(jù)EJB規(guī)范,要想將EJB成功地部署到EJB服務(wù)器上,必須為EJB服務(wù)器提供相應(yīng)的部署描述符。部署描述符對(duì)所要部署的EJB進(jìn)行了說(shuō)明,包括該EJB的遠(yuǎn)程描述符、本地描述符和Bean類等信息。由于EJB服務(wù)器只有在獲得這些基本信息后才能正確完成EJB的部署,因此編寫(xiě)EJB描述符是開(kāi)發(fā)EJB時(shí)必不可少的一個(gè)環(huán)節(jié)。

          對(duì)于不同的EJB服務(wù)器來(lái)說(shuō),部署同一EJB時(shí)所需的部署描述符可能并不相同。在JBoss平臺(tái)上,任何將要被部署的EJB都必須提供ejb-jar.xml和jboss.xml兩個(gè)文件,這兩個(gè)文件均位于JAR包中的META-INF目錄下,用于對(duì)將要部署的EJB進(jìn)行簡(jiǎn)要的說(shuō)明。

          ejb-jar.xml

          ejb-jar.xml是EJB規(guī)范定義的標(biāo)準(zhǔn)部署描述符,在任何EJB服務(wù)器上部署EJB時(shí)都需要用到該部署描述符。本例中用到的ejb-jar.xml代碼如下所示:

          <?xml version="1.0" encoding="Cp1252"?>
          <ejb-jar>
          <description>jBoss test application </description>
          <display-name>Test</display-name>
          <enterprise-beans>
          <session>
          <ejb-name>GreetEJB</ejb-name>
          <home>greet.GreetHome</home>
          <remote>greet.Greet</remote>
          <ejb-class>greet.GreetBean</ejb-class>
          <session-type>Stateless</session-type>
          <transaction-type>Bean</transaction-type>
          </session>
          </enterprise-beans>
          </ejb-jar>


          jboss.xml

          雖然ejb-jar.xml對(duì)所有的EJB服務(wù)器都是通用的,但它并沒(méi)有為EJB服務(wù)器提供將要被部署的EJB的全部信息。為了能夠?qū)JB的部署進(jìn)行更靈活的控制,大部分EJB服務(wù)器都要求EJB開(kāi)發(fā)者同時(shí)提供另外一個(gè)文件來(lái)對(duì)將要部署的EJB進(jìn)行描述,在JBoss中該文件為jboss.xml,它也位于JAR包中的META-INF目錄中。jboss.xml中可以對(duì)EJB對(duì)應(yīng)的JNDI名字以及相應(yīng)的持久性進(jìn)行說(shuō)明,在本例中用到的jboss.xml如下所示:

          <?xml version="1.0" encoding="ISO-8859-1"?>
          <jboss>
          <enterprise-beans>
          <session>
          <ejb-name>GreetEJB</ejb-name>
          <jndi-name>GreetingEJB</jndi-name>
          </session>
          <secure>false</secure>
          </enterprise-beans>
          <resource-managers/>
          </jboss>


          部署EJB



          開(kāi)發(fā)EJB的最后一步是將其中所有的類文件和相應(yīng)的部署描述符壓縮成JAR包,然后部署到EJB服務(wù)器上。在本例中,JAR包的生成可以通過(guò)下面這條命令來(lái)實(shí)現(xiàn):

          jar cf greetejb.jar greet/*.class META-INF/*.xml


          該命令將greet目錄下的.class文件和META-INF目錄下的.xml文件壓縮成greetejb.jar文件。如果想知道生成的JAR包是否正確地包含了所有的文件,可以用命令:

          jar cvf greetejb.jar


          來(lái)查看greetejb.jar中包含的文件。如果得到如下的類似信息,則說(shuō)明所需的文件都已經(jīng)被正確地包含在該壓縮包中了,信息如下:

          0 Sun May 24 15:32:10 CST 2002 META-INF/
          68 Sun May 24 15:32:10 CST 2002 META-INF/MANIFEST.MF
          1007 Sun May 24 14:35:46 CST 2002 greet/GreetBean.class
          209 Sun May 24 14:35:46 CST 2002 greet/Greet.class
          251 Sun May 24 14:35:46 CST 2002 greet/GreetHome.class
          493 Sun May 24 08:40:00 CST 2002 META-INF/ejb-jar.xml
          303 Sun May 24 08:43:22 CST 2002 META-INF/jboss.xml


          生成的JAR包在JBoss上的部署相當(dāng)簡(jiǎn)單,只需要將該文件復(fù)制到JBoss的deploy目錄下就可以了,命令如下:

          cp greetejb.jar /usr/jb_tom/jboss/deploy/


          JBoss支持熱部署,deploy目錄下所有文件的改變都會(huì)被JBoss自動(dòng)檢測(cè)到,并根據(jù)檢測(cè)結(jié)果對(duì)相應(yīng)的EJB進(jìn)行
          [INFO,ContainerFactory] Deploying GreetEJB
          [INFO,GreetEJB] Initializing
          [INFO,GreetEJB] Initialized
          [INFO,GreetEJB] Starting
          [INFO,GreetEJB] Started


          至此,EJB在JBoss平臺(tái)上的部署就全部完成了,如果想知道該EJB能否正常地工作,則需要為其編寫(xiě)專門(mén)的客戶端程序進(jìn)行測(cè)試。

          測(cè)試EJB



          EJB存在的價(jià)值在于為其客戶提供相應(yīng)的服務(wù),EJB客戶包含的范圍相當(dāng)廣泛,可以是另外的EJB、普通的JavaBean、JSP頁(yè)面、Applet或者標(biāo)準(zhǔn)的Java應(yīng)用程序。GreetClient.java是已經(jīng)部署好的EJB的客戶程序,其完整的源碼如下所示:

          import javax.naming.*;
          import java.util.Hashtable;
          import javax.rmi.PortableRemoteObject; 
          import greet.*;
          class GreetClient
          {
           public static void main(String[] args) {
            System.setProperty("java.naming.factory.initial", 
          "org.jnp.interfaces.Naming ContextFactory");
            System.setProperty("java.naming.provider.url", 
          "localhost:1099");
          try {
             // Get a naming context
             InitialContext jndiContext = new InitialContext();
            System.out.println("Got context");
           Object ref  = jndiContext.lookup("GreetingEJB");
            System.out.println("Got reference");
           GreetHome home = (GreetHome) 
             PortableRemoteObject.narrow (ref, GreetHome.class);
             Greet greet = home.create();
             System.out.print("The magic number from server is ");
          System.out.println(greet.calculateMagic(123.456));
            } catch(Exception e) {
             System.out.println(e.toString());
            }
           }
          }


          用下面的命令對(duì)EJB客戶端程序進(jìn)行編譯:

          javac GreetClient.java \
          -classpath /usr/jb_tom/jboss/lib/ext/jboss-j2ee.jar:.


          如果一切正常,就可以運(yùn)行客戶端程序來(lái)對(duì)EJB進(jìn)行測(cè)試了,命令如下:

          java -cp \ 
          $CLASSPATH:/usr/jb_tom/jboss/client/jboss-client.jar:. \
          GreetClient


          小結(jié)



          本文以一個(gè)無(wú)狀態(tài)的會(huì)話Bean為例,講述了在JBoss平臺(tái)上開(kāi)發(fā)和部署EJB的全過(guò)程,對(duì)JBoss的安裝、EJB的創(chuàng)建、EJB的部署及EJB的測(cè)試做了簡(jiǎn)要介紹。作為一個(gè)開(kāi)放源碼的EJB服務(wù)器,JBoss已經(jīng)開(kāi)始被越來(lái)越多的企業(yè)所接受,基于JBoss的成功案例屢見(jiàn)不鮮。有關(guān)JBoss的更多信息,請(qǐng)?jiān)L問(wèn)JBoss的網(wǎng)站http://www.jboss.org。

          posted @ 2007-02-27 22:11 chenweicai 閱讀(244) | 評(píng)論 (0)編輯 收藏

          jdk是java?develop?kit?--?java開(kāi)發(fā)包
          j2sdk是java?2?software?develop?kit?--?java2軟件開(kāi)發(fā)包

          實(shí)際上jdk和j2sdk是基本同樣的。
          j2sdk呢有幾個(gè)版本對(duì)應(yīng)于java2的幾個(gè)版本,其中j2ee需要用到開(kāi)發(fā)工具就是J2eesdk了,只不過(guò)大部分應(yīng)用服務(wù)器(weblogic?jboss等)都內(nèi)置了j2eesdk。

          當(dāng)然了,j2sdk標(biāo)準(zhǔn)版是基礎(chǔ),所以要安裝先;j2eesdk因?yàn)槭瞧髽I(yè)應(yīng)用嘛,所以是注冊(cè)后才能下載

          至于jre是java?runtime?envionment?--?java運(yùn)行環(huán)境,jdk中包括了它,但是對(duì)于不需要開(kāi)發(fā)只是運(yùn)行的用戶是可以只單獨(dú)安裝jre的,所以sun提供了jre的下載。



          JDK和J2SDk:

          J2SDk包含了Java?Development?kit(JDK)、Java?Runtime?Environment(JRE)和Java?Plug-in。原先sun的JAVA軟件開(kāi)發(fā)工具包是JDK,現(xiàn)在就稱為J2SDk了。?

          JRE和plug-in:JRE包含了java?plug-in。?

          sun的java網(wǎng)站上就單獨(dú)提供J2SDK和JRE各種版本的下載,J2SDk是提供給開(kāi)發(fā)JAVA程序所?
          用,應(yīng)用程序用戶是不需要開(kāi)發(fā)工具的。而JRE顧名思義是JAVA程序要運(yùn)行所需要的環(huán)境?
          ,所謂跨平臺(tái)就是要各種平臺(tái)都有一個(gè)中間代理,那就是JRE。一般采用JAVA技術(shù)開(kāi)發(fā)出?
          的軟件都得帶這個(gè),所以sun就單獨(dú)提供了JRE安裝文件,以供JAVA應(yīng)用程序發(fā)布時(shí)所用。?

          Swing和JFC(Java?Foundation?Class)JFC是早期Sun對(duì)JDK的功能擴(kuò)展,不是Java的公共?
          規(guī)范,Swing是其中的一項(xiàng)用戶界面擴(kuò)展技術(shù)。最新的JAVA2技術(shù)則包含了JFC技術(shù),不需?
          要再擴(kuò)展了。說(shuō)白了,其實(shí)就是Sun將JFC納入了JAVA核心類庫(kù)。原先要用到JFC技術(shù),用?
          戶必須在原有的JRE前提下再添加JFC,現(xiàn)在少了一步,只需JRE了。

          J2ME——Java?2?Micro?Edition
          J2SE——Java?2?Standard?Edition
          J2EE——Java?2?Enterprise?Edition
          如需要進(jìn)行開(kāi)發(fā),必須安裝J2SE,因?yàn)閖avac、jdb等工具由提供。

          posted @ 2007-02-27 18:39 chenweicai 閱讀(324) | 評(píng)論 (0)編輯 收藏

          Java

          Description

          Executes a Java class within the running (Ant) VM or forks another VM if specified.

          If odd things go wrong when you run this task, set fork="true" to use a new JVM.

          As of Ant 1.6.3, you can interact with a forked VM, as well as sending input to it via the input and inputstring attributes.

          Parameters

          Attribute Description Required
          classname the Java class to execute. Either jar or classname
          jar the location of the jar file to execute (must have a Main-Class entry in the manifest). Fork must be set to true if this option is selected. See notes below for more details. Either jar or classname
          args the arguments for the class that is executed. deprecated, use nested <arg> elements instead. No
          classpath the classpath to use. No
          classpathref the classpath to use, given as referenceto a PATH defined elsewhere. No
          fork if enabled triggers the class execution in another VM (disabled by default) No
          spawn if enabled allows to start a process which will outlive ant.
          Requires fork=true, and not compatible with timeout, input, output, error, result attributes.
          (disabled by default)
          No
          jvm the command used to invoke the Java Virtual Machine, default is 'java'. The command is resolved by java.lang.Runtime.exec(). Ignored if fork is disabled. No
          jvmargs the arguments to pass to the forked VM (ignored if fork is disabled). deprecated, use nested <jvmarg> elements instead. No
          maxmemory Max amount of memory to allocate to the forked VM (ignored if fork is disabled) No
          failonerror Stop the buildprocess if the command exits with a returncode other than 0. Default is "false" (see note) No
          resultproperty The name of a property in which the return code of the command should be stored. Only of interest if failonerror=false and if fork=true. No
          dir The directory to invoke the VM in. (ignored if fork is disabled) No
          output Name of a file to which to write the output. If the error stream is not also redirected to a file or property, it will appear in this output. No
          error The file to which the standard error of the command should be redirected. No
          logError This attribute is used when you wish to see error output in Ant's log and you are redirecting output to a file/property. The error output will not be included in the output file/property. If you redirect error with the "error" or "errorProperty" attributes, this will have no effect. No
          append Whether output and error files should be appended to or overwritten. Defaults to false. No
          outputproperty The name of a property in which the output of the command should be stored. Unless the error stream is redirected to a separate file or stream, this property will include the error output. No
          errorproperty The name of a property in which the standard error of the command should be stored. No
          input A file from which the executed command's standard input is taken. This attribute is mutually exclusive with the inputstring attribute No; default is to take standard input from console (unless spawn="true")
          inputstring A string which serves as the input stream for the executed command. This attribute is mutually exclusive with the input attribute. No; default is to take standard input from console (unless spawn="true")
          newenvironment Do not propagate old environment when new environment variables are specified. Default is "false" (ignored if fork is disabled). No
          timeout Stop the command if it doesn't finish within the specified time (given in milliseconds). It is highly recommended to use this feature only if fork is enabled. No
          clonevm If set to true true, then all system properties and the bootclasspath of the forked Java Virtual Machine will be the same as those of the Java VM running Ant. Default is "false" (ignored if fork is disabled). since Ant 1.7 No

          Parameters specified as nested elements

          arg and jvmarg

          Use nested <arg> and <jvmarg> elements to specify arguments for the Java class and the forked VM respectively. See Command line arguments.

          sysproperty

          Use nested <sysproperty> elements to specify system properties required by the class. These properties will be made available to the VM during the execution of the class (either ANT's VM or the forked VM). The attributes for this element are the same as for environment variables.

          syspropertyset

          You can specify a set of properties to be used as system properties with syspropertysets.

          since Ant 1.6.

          classpath

          Java's classpath attribute is a PATH like structureand can also be set via a nested classpath element.

          bootclasspath

          The location of bootstrap class files can be specified using this PATH like structure- will be ignored if fork is not true or the target VM doesn't support it (i.e. Java 1.1).

          since Ant 1.6.

          env

          It is possible to specify environment variables to pass to the forked VM via nested env elements. See the description in the section about exec

          Settings will be ignored if fork is disabled.

          permissions

          Security permissions can be revoked and granted during the execution of the class via a nested permissions element. For more information please see permissions

          When the permission RuntimePermission exitVM has not been granted (or has been revoked) the System.exit() call will be intercepted and treated like indicated in failonerror.

          Note:
          If you do not specify permissions, a set of default permissions will be added to your Java invocation to make sure that the ant run will continue or terminated as indicated by failonerror. All permissions not granted per default will be checked by whatever security manager was already in place. exitVM will be disallowed.

          Settings will be ignored if fork is enabled.

          since Ant 1.6.

          assertions

          You can control enablement of Java 1.4 assertions with an <assertions>subelement.

          Assertion statements are currently ignored in non-forked mode.

          since Ant 1.6.

          redirector

          Since Ant 1.6.2

          A nested I/O Redirectorcan be specified. In general, the attributes of the redirector behave as the corresponding attributes available at the task level. The most notable peculiarity stems from the retention of the <java> attributes for backwards compatibility. Any file mapping is done using a null sourcefile; therefore not all Mappertypes will return results. When no results are returned, redirection specifications will fall back to the task level attributes. In practice this means that defaults can be specified for input, output, and error output files.

          Errors and return codes

          By default the return code of a <java> is ignored. Alternatively, you can set resultproperty to the name of a property and have it assigned to the result code (barring immutability, of course). When you set failonerror="true", the only possible value for resultproperty is 0. Any non-zero response is treated as an error and would mean the build exits.

          Similarly, if failonerror="false" and fork="false" , then <java>must return 0 otherwise the build will exit, as the class was run by the build JVM.

          JAR file execution

          The parameter of the jar attribute is of type File; that is, the parameter is resolved to an absolute file relative to the base directory of the project, not the directory in which the Java task is run. If you need to locate a JAR file relative to the directory the task will be run in, you need to explicitly create the full path to the JAR file.

          When using the jar attribute, all classpath settings are ignored according to Sun's specification.

          Examples

          				       <java classname="test.Main">
                   <arg value="-h"/>
                   <classpath>
                     <pathelement location="dist/test.jar"/>
                     <pathelement path="${java.class.path}"/>
                   </classpath>
                 </java>
          
          		
          Run a class in this JVM with a new jar on the classpath
          				       <java jar="dist/test.jar"
                     fork="true"
                     failonerror="true"
                     maxmemory="128m"
                     >
                   <arg value="-h"/>
                   <classpath>
                     <pathelement location="dist/test.jar"/>
                     <pathelement path="${java.class.path}"/>
                   </classpath>
                 </java>
          
          		
          Run the JAR test.jar in this project's dist/lib directory. using the manifest supplied entry point, forking (as required), and with a maximum memory of 128MB. Any non zero return code breaks the build.
          				       <java
                     dir="${exec.dir}"
                     jar="${exec.dir}/dist/test.jar"
                     fork="true"
                     failonerror="true"
                     maxmemory="128m"
                     >
                   <arg value="-h"/>
                   <classpath>
                     <pathelement location="dist/test.jar"/>
                     <pathelement path="${java.class.path}"/>
                   </classpath>
                 </java>
          
          		
          Run the JAR dist/test.jar relative to the directory ${exec.dir}, this being the same directory into which the JVM is to start up.
          				  <java classname="test.Main"/>
          		
          Runs a given class with the current classpath.
          				  <java classname="test.Main"
                  fork="yes" >
              <sysproperty key="DEBUG" value="true"/>
              <arg value="-h"/>
              <jvmarg value="-Xrunhprof:cpu=samples,file=log.txt,depth=3"/>
            </java>
          
          		
          Add system properties and JVM-properties to the JVM as in java ="-Xrunhprof:cpu=samples,file=log.txt,depth=3 -DDEBUG=true test.Main
          				  <java classname="ShowJavaVersion" classpath="."
                  jvm="path-to-java14-home/bin/java" fork="true"
                  taskname="java1.4" >
          
          		
          Use a given Java implementation (another the one Ant is currently using) to run the class. For documentation in the log taskname is used to change the [java] log-prefix to [java1.4].

          Note: you can not specify the (highly deprecated) MSJVM, "jview.exe" as the JVM, as it takes different parameters for other JVMs, That JVM can be started from <exec> if required.

          posted @ 2007-01-31 20:12 chenweicai 閱讀(1300) | 評(píng)論 (0)編輯 收藏

          package proxy;
          /**
          ?*
          ?* @author chen
          ?*
          ?*/
          public interface Subject {
          ?abstract public void request();
          ?abstract public void request2();
          }


          package proxy;

          /**
          ?*
          ?* @author chen
          ?*
          ?*/
          public class RealSubject implements Subject {
          ?
          ?public RealSubject(){
          ?}

          ?public void request() {
          ??// TODO Auto-generated method stub
          ??System.out.println("From real subject.request().");
          ?}
          ?
          ?public void request2() {
          ??// TODO Auto-generated method stub
          ??System.out.println("From real subject.request2()");
          ?}
          }

          package proxy;


          import java.lang.reflect.InvocationHandler;
          import java.lang.reflect.Method;

          /**
          ?*
          ?* @author chenweicai
          ?*
          ?*/
          public class DynamicSubject implements InvocationHandler {
          ?
          ?private Object sub;
          ?
          ?public DynamicSubject(){
          ?}
          ?
          ?public DynamicSubject(Object obj){
          ??this.sub = obj;
          ?}

          ?public Object invoke(Object proxy, Method method, Object[] args)
          ???throws Throwable {
          ??// TODO Auto-generated method stub
          ???? System.out.println("before calling " + method);
          ???? method.invoke(sub,args);
          ???? System.out.println("after calling " + method);
          ??return null;
          ?}

          }


          package proxy;

          import java.lang.reflect.InvocationHandler;
          import java.lang.reflect.Method;
          import java.lang.reflect.Constructor;
          import java.lang.reflect.Proxy;

          /**
          ?*
          ?* @author chen
          ?*
          ?*/
          public class Client {
          ?static public void main(String[] args)
          ??????? throws Throwable{
          ??? RealSubject rs = new RealSubject();? //在這里指定被代理類
          ??? InvocationHandler ds = new DynamicSubject(rs);? //初始化代理類
          ??? Class cls = rs.getClass();
          ??
          ??? //以下是分解步驟
          ??? /*Class c = Proxy.getProxyClass(cls.getClassLoader(),cls.getInterfaces()) ;
          ??? Constructor ct=c.getConstructor(new Class[]{InvocationHandler.class});
          ??? Subject subject =(Subject) ct.newInstance(new Object[]{ds});*/
          ??
          ??? //以下是一次性生成
          ??? Subject subject = (Subject) Proxy.newProxyInstance(cls.getClassLoader(),
          ??? cls.getInterfaces(),ds );

          ??? subject.request2();
          ?? }
          }

          posted @ 2007-01-05 20:47 chenweicai 閱讀(394) | 評(píng)論 (1)編輯 收藏

          僅列出標(biāo)題
          共6頁(yè): 上一頁(yè) 1 2 3 4 5 6 下一頁(yè) 
          主站蜘蛛池模板: 淮安市| 余姚市| 大新县| 新干县| 女性| 梅州市| 宣威市| 河东区| 横峰县| 南昌县| 鹿邑县| 来安县| 那坡县| 万载县| 封开县| 界首市| 宁德市| 乐安县| 黑龙江省| 阿尔山市| 布尔津县| 平南县| 清新县| 铁岭市| 贵定县| 郎溪县| 清涧县| 土默特右旗| 乡城县| 太原市| 景德镇市| 高阳县| 深圳市| 昭通市| 台南市| 和林格尔县| 申扎县| 若尔盖县| 都匀市| 射洪县| 麻城市|