久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

EJB 3.0簡介

 bluecrystal 2006-06-03
EJB 3.0簡介

SUN中國軟件技術(shù)中心 王強 [email protected]

1 簡化開發(fā)的目標(biāo)

1.1我們的目標(biāo)

EJB3.0是當(dāng)前很多人談?wù)摰脑掝},企業(yè)軟件開發(fā)的一個關(guān)鍵是,,提供一個盡量簡單的的應(yīng)用框架:它可以使開發(fā)人員不用關(guān)注于復(fù)雜的問題,比如事務(wù)處理,、安全和持久化等,。可以集中精力關(guān)注于商業(yè)邏輯,,而不用關(guān)心那些低層的技術(shù)細(xì)節(jié),,從而提高開發(fā)者的效率,得到高質(zhì)量的軟件,。這也是制定EJB 3.0規(guī)范的目標(biāo),,簡化開發(fā)!


1.2 當(dāng)前的問題


EJB3.0希望開發(fā)人員能夠從這種新的開發(fā)模式中受益,更好地推進J2EE的應(yīng)用. 隨著JAVA不斷的進步和發(fā)展,,越來越多的企業(yè)選擇J2EE作為它們的解決方案,,J2EE體系結(jié)構(gòu)提供一個簡化的中間層集成框架來滿足應(yīng)用的需求。然而,,對于一般的開發(fā)人員,,目前J2EE 1.4下的EJB 2.1 框架有些過于復(fù)雜了。 按照EJB2.1規(guī)范的定義,,EJB組件必須事先很多的接口,, 比如Home接口、Remote接口,、local 接口,,等等.還要針對各種應(yīng)用類型定義許多的xml描述文件,。當(dāng)我們需要訪問某個組件或者服務(wù)的時候,必須通過JDNI查找,,通過名字綁定服務(wù),,才能找到我們需要的對象。

比如我們要使用某個EJB shopping cart, 就要首先實現(xiàn)一個initial context,,然后通過他查找這個EJB 的home 接口,然后調(diào)用home街口的create方法,,得到一個EJB object, 最后調(diào)用這個EJB object的商務(wù)方法. 下面是一個例子:
// EJB 2.1 Client view of the ShoppingCart Bean
...
Context initialContext = new InitialContext();
ShoppingCartHome myCartHome = (ShoppingCartHome)
initialContext.lookup(“JAVA:comp/env/ejb/cart”);
ShoppingCart myCart= myCartHome.create();
//Use the Bean
Collection widgets = myCart.startToShop(Widgets )
...
// Don‘t forget code to handle JAVAx.ejb.CreateException
...
EJB2.1的規(guī)范還要求我們必須實現(xiàn)Javax.EJB里面定義的接口, 實現(xiàn)里面的Methods比如 EJBCreate(), EJBPassivate(), and EJBActivate()。大多數(shù)情況下這些方法是不需要開發(fā)人員作任何修改的,。這些規(guī)定實際上都和真正核心的商務(wù)邏輯沒什么關(guān)系,都只是一些技術(shù)模板,規(guī)定了開發(fā)人員必須按照這樣的模板進行開發(fā). 比如下面這段代碼:

人們開始思考,,怎么樣才能把EJB的開發(fā)變的更加簡單,更好的利用這種技術(shù). 當(dāng)前正在制定的EJB 3.0的標(biāo)準(zhǔn)的目標(biāo)就是簡化開發(fā),, 讓更多的開發(fā)人員被它的易用和強大功能所吸引過來,,喜愛這項技術(shù)。為了達到這個目標(biāo),,要做的第一件事情,,也是最重要的事情,就是從一個開發(fā)人員的角度,,將EJB的使用盡量的簡化,。

1.3 JCP專家組的工作


這個工作是由EJB3.0 專家組來完成的。我們知道JAVA的開發(fā)和推動是由一個開放的組織來完成的,,這個組織的名字叫做JAVA Community Process,。簡稱JCP. SUN的理念是: 創(chuàng)新無處不在. 所以JCP小組從世界的每個角落聽取關(guān)于JAVA的建議,將各方面對JAVA的要求通過制定JSR(JAVA Specification Request )形式確定下來. EJB 3.0規(guī)范的JSR編號是 220. 整個專家組的制定成員包括J2EE 注冊用戶, 應(yīng)用服務(wù)器的開發(fā)廠商和J2EE社區(qū)的成員.


簡化一個現(xiàn)有的技術(shù),尤其是得到廣泛的開發(fā)人支持的技術(shù),比如EJB, 不是一個簡單的工作. 作為鋪墊,專家組進行了大量的準(zhǔn)備工作,檢驗了EJB技術(shù)的復(fù)雜性,,當(dāng)前EJB流域流行的各種模式和反模式,,以及從客戶和開發(fā)人員來的各種需求。開發(fā)人員和用戶根據(jù)實際的需要,,希望EJB能夠提供他們滿意的特性.
檢驗結(jié)果發(fā)現(xiàn),,大多數(shù)情況下,人們不需要更高級的技術(shù),,而是需要更簡化的技術(shù),,來簡化當(dāng)前的開發(fā)模式。而不是像以前的EJB發(fā)布一樣,,在技術(shù)復(fù)雜度上的提高,。定義一個新技術(shù),不僅對老的技術(shù)有一定的更新, 也要能充分并容老的技術(shù), 提供一定的向后兼容性. 因為采用這些技術(shù)的企業(yè),已經(jīng)在這些技術(shù)上投資了很多. 如果因為技術(shù)的更新就使得對應(yīng)的IT系統(tǒng)和數(shù)據(jù)變得不能使用,是一件非常糟糕的事情.


所以,定義了EJB3.0規(guī)范的同時,如何支持現(xiàn)有的EJB技術(shù)是非常必要的. 要保證現(xiàn)有的EJB API是持續(xù)可用的, 還要和新的EJB3.0 API結(jié)合起來, 對早期的API應(yīng)該繼續(xù)提供支持而不是標(biāo)記為不贊成使用

1.4 標(biāo)注的新功能


EJB3.0的很多新特性是通過JAVA SE5.0來實現(xiàn)的。這里我們就要談到JAVA SE 5.0,,它所提供的許多特性,其中最有趣的一點就是標(biāo)注(Annotation)的功能,。我們知道以前的JAVA語言都是命令格式的, 比如a.b(), 表示讓類a做事情b, 但是很多時候我們只是需要對某個對象做一些注解,比如對某個類標(biāo)記為可持續(xù)化的Serializable. 這只是一個標(biāo)記,為了以后的處理提供說明,,本身不需要做任何操作,。
在Deploy 的時候, 提供了很多說明的XML文件,比如部署描述文件,里面說明了引用的EJB的名字,接口, 以及當(dāng)前EJB的Transaction Type等等信息. 所有這些信息都是說明性的,而不是命令性的. 用來對某個對象的某個屬性坐一段說明. 因此,有一個非常有趣的想法,能不能通過對JAVA語言的擴展,結(jié)合標(biāo)注和命令這兩者的優(yōu)點 ?


這也是有一個專家組在JCP的組織內(nèi)完成的, JSR規(guī)范的編號是JSR 175, 為JAVA SE 5.0支持注解(Annotation)的功能. 這個規(guī)范為EJB3.0 的簡化實現(xiàn)提供了一些基本的支持, 也是最關(guān)鍵的支持. 標(biāo)注可以有自己的屬性,也可以定義自己的持續(xù)時間,表示這段信息是否保存到 源代碼中,還是一直持續(xù)到Class中,或者一直保持到運行時間. 標(biāo)注有自己的缺省值.大多數(shù)情況下,無須說明我們就可以推算出來這個對象的行為,。 
2 輕松的實現(xiàn)開發(fā)

2.1 減輕開發(fā)人員的負(fù)擔(dān)

EJB3.0的簡化工作包括下面幾個部分:
提供一個簡化的API, 包括對EJB的定義,對EJB的引用等等
減少開發(fā)的類數(shù)目,不再需要那么多的interface
相關(guān)性注入
簡化的查詢機制
從開發(fā)人員的角度不必要使用部署描述文件, 很多的工作可以放到代碼里面用標(biāo)注來說明,比如Entity Bean 的Transaction Type
簡化的持久化功能
簡化和改善數(shù)據(jù)對象的O/R Mapping.


標(biāo)注可以應(yīng)用到編程語言的一些基本元素上,,比如類,,方法,變量,,包等等. 當(dāng)我們在代碼中使用了這些標(biāo)注, 根據(jù)這個標(biāo)注對應(yīng)的持續(xù)策略, 它可以被編譯到Class 文件中去,或者一直保持到運行的時候,。大多數(shù)在 EJB 3.0 中定義的標(biāo)注都是Runtime保持策略, 這樣做的好處是提供了最大的靈活性,。而且由于大量工作放到了運行的時候來做,也減少一部分Deploy的工作,。


我們通過定義缺省的語法來說明大多數(shù)常見的情況,。開發(fā)人員不需要再專門說明常見的情況,“OK, 沒問題,,缺省的設(shè)置就已經(jīng)可以滿足需要了“ 這樣,,開發(fā)人員的工作大大減輕了。
這也引出來了EJB3.0中的一個很有意思的概念 "Configuration By Exception" --只有在例外的情況下才需要我們的參與.


EJB3.0的目標(biāo)是簡化開發(fā)人員的工作,,讓他們專注于商務(wù)應(yīng)用的開發(fā)而不是把精力放到很多繁瑣的例行工作上,,這些工作可以交給Container來完成。EJB通過注入來指定自己需要的資源,不用再寫那些麻煩的方法. 將對象的創(chuàng)建和獲取提取到外部,。由外部容器提供需要的組件,。這樣,開發(fā)人員只用在開始的時候定義,說我需要這個資源, 后面就可以直接使用這個資源, 這樣會大大的簡化開發(fā), 因為開發(fā)人員只用關(guān)心如何使用這個對象和商務(wù)方法, 而不用擔(dān)心其他的技術(shù)細(xì)節(jié)。

2.2 拋開繁瑣的細(xì)節(jié)
下面我們看看都作了那些簡化,。我們的目的是把那些繁瑣的技術(shù)細(xì)節(jié)隱藏起來,,程序開發(fā)人員只用關(guān)心自己的商務(wù)邏輯代碼,而不用關(guān)心那些復(fù)雜的技術(shù)模板,,必須實現(xiàn)的接口等,,哪怕這些方法和接口根本不需要實現(xiàn).

不再需要EJB的部件接口
每個EJB 都只是一個普通的JAVA Class
不再需要home接口, 我們不再用home 來創(chuàng)建這個EJB
不再需要實現(xiàn)javax.ejb.EnterpriseBean借口
對于需要在回調(diào)方法里實現(xiàn)的部分,我們采用標(biāo)注的方式說明一個方法為回調(diào)方法
不再需要使用復(fù)雜的JNDI名字調(diào)用機制,,對于需要服務(wù)或者資源的地方
我們采用了相關(guān)性注入的方法,,另外也可以通過簡化的lookup方法來查找資源

下面讓我們看一個簡單的無狀態(tài)SessionBean的例子。無狀態(tài)session Bean是最簡單也是最常用 Bean,,很多初學(xué)EJB的人都從無狀態(tài)Session Bean開始,。如何讓無狀態(tài)Session Bean 變的簡單易用成為一個非常有意義的話題。

前面假設(shè)我們已經(jīng)定義了相關(guān)的interface, 這個EJB2.1的的功能是對員工的工資做處理,打開一個數(shù)據(jù)庫連接,進行員工工資信息的某些操作,等等.

// EJB 2.1
public Class PayrollBean implements JAVAx.ejb.SessionBean
{
SessionContext ctx;
DataSource empDB;
public void setSessionContext(SessionContext ctx) {
this.ctx = ctx;
}
public void ejbCreate() {
Context initialContext = new InitialContext();
empDB = (DataSource)initialContext.lookup( JAVA:comp/env/jdbc/empDB );
}
public void ejbActivate() {}
public void ejbPassivate() {}
public void ejbRemove() {}
public void setBenefitsDeduction (int empId, double deduction) {
...
Connection conn = empDB.getConnection();
...
}
...
}
// NOTE deployment descriptor needed


這里我們首先要實現(xiàn)一個 sessionBean interface,,保持一個對sessioncontext的引用,,然后是在EJBcreate 方法里面我們調(diào)用JNDI得到一個datasource。 后面我們必須要定義一些回調(diào)方法,,雖然這些方法我們不會實現(xiàn)任何邏輯,。然后在 商務(wù)方法里面,,我們打開一個數(shù)據(jù)庫連接。

注意,,我們還沒有完,。為了使用這個EJB, 必須加上xml的部署描述文件打好包。

下面是一個常見的部署描述文件可以是這樣子的,。

<session>
<ejb-name>PayrollBean</ejb-name>
<local-home>PayrollHome</local-home>
<local>Payroll</local>
<ejb-class>com.example.PayrollBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<resource-ref>
<res-ref-name>jdbc/empDB</res-ref-name>
<res-ref-type>javax.sql.DataSource</res-ref-type>
<res-auth>Container</res-auth>
</resource-ref>
</session>
...
<assembly-descriptor>
...
</assembly-descriptor>

從開發(fā)人員的角度來檢查這樣一個簡單的EJB 是非常有意義的,。我們可以更好的理解有那些地方可以有改動。一個主要的問題是,,定義了這么多的方法和結(jié)構(gòu)以后,,程序的清晰化受到了影響,結(jié)構(gòu)變得混亂,。真正需要關(guān)注的商務(wù)方法沒有很好的強調(diào)和體現(xiàn),。

下面讓我們看一看EJB 3.0 是如何實現(xiàn)一個簡單的stateless session Bean的。

// Same example, EJB 3.0
@Stateless public class PayrollBean implements Payroll {
@Resource DataSource empDB;
public void setBenefitsDeduction (int empId, double deduction) {
...
Connection conn = empDB.getConnection();
...
}
...
}


@Stateless 標(biāo)注表示這是一個stateless session Bean. 使用這樣的標(biāo)注可以讓我們不再需要使用SessionBean 接口,, 這樣就大大的簡化了EJB的實現(xiàn)類,。 Bean的商務(wù)接口是payroll. 這是一個普通的JAVA interface. 缺省的情況,container會把他作成一個local interface. 如果需要實現(xiàn)一個遠程接口,,只需再定義一個標(biāo)注 @Remote. 注意在接口里面不需要定義 RemoteExceptions,,它由Container 層在后面處理掉了

2.3 引用對象的新方法
在老的EJB規(guī)范中,還有一個比較復(fù)雜的地方是訪問環(huán)境對象,。EJB 2.1 里面訪問環(huán)境要首先在組件定義的相關(guān)性引用,,比如resource-refs, EJB-refs, 然后在JNDI名字空間里面配置這些環(huán)境對象。 最后查找運行的時候JNDI空間里面查找這些環(huán)境對象
EJB 3.0對此提供了兩種簡化的方案:

1) 相關(guān)性注入
2) 一個簡化的查詢lookup方法

相關(guān)性注入是一種技術(shù),,開發(fā)人員在原代碼中加入標(biāo)注的一個定義,,說明需要這個環(huán)境對象,然后由Container在初始化的時候把真的環(huán)境對象注入里面,。
目前EJB3.0 spec里面有兩種注入方式,,setter注入和變量注入, 這些在以后的規(guī)范中可能會有變化,比如一種統(tǒng)一的注入方式,。 我們可以通過注入標(biāo)記@EJB來定義一個EJB的引用,,也可以通過注入標(biāo)記@resource 表示我們要引用一個資源,它可以是EJB以外的一切環(huán)境對象. 專家組為了盡可能的簡化開發(fā),,將使用注入的對象類型作了簡化,。

EJB3.0 將仍然提供一個動態(tài)查詢的方法,但是從程序開發(fā)人員的角度,,不需要再使用JNDI API,,而是采用更為簡化的EJB Context 的 Lookup方法。

在新的EJB 3.0規(guī)范中,,因為不再需要復(fù)雜的home接口和EJB 接口,。EJB client端的編碼也大大的簡化了,,和訪問一個普通的JAVA 對象沒有什么區(qū)別。上面的那個EJB2.1的例子比較起來,,在EJB 3.0 里面使用一個EJB變的非常簡單,,只需要兩行代碼:

// EJB 3.0 client view
@EJB ShoppingCart myCart;
...
Collection widgets = myCart.startToShop(Widgets );
...

首先定義一個EJB的應(yīng)用,然后就可以直接調(diào)用這個EJB的商務(wù)方法,,剩下的工作由Container來為我們完成,。

2.4 新的事務(wù)管理

EJB中的事務(wù)(Transaction)管理大大簡化了用戶開發(fā)程序。把應(yīng)用分成一個一個小的單元,,叫做transaction. 事務(wù)系統(tǒng)保證了這個單元里面的任務(wù)是完整的,,要么全部執(zhí)行,要么出錯后完全退回到初始狀態(tài),。


J2EE中有兩種類型的事務(wù), 容器管理的和Bean管理的,。他們在如何啟動和結(jié)束事務(wù)上是不同的,。Bean 管理的事務(wù)由組件使用 UserTransaction類顯式啟動和結(jié)束的。代碼中需要調(diào)用方法 UserTransaction.begin() 和 UserTransaction.commit() ,。Container 管理的事物是由container 自動來完成的,。
針對不同的事務(wù)類型,可以定義6種不同的事務(wù)屬性,。
事務(wù)屬性告訴 Container 是否把EJB方法里面的工作放到用戶的事務(wù)里面,。還是針對這個方法重新啟動一個新的事務(wù). 或者執(zhí)行這個方法而不包含在事務(wù)里面,等等,。
在EJB3.0規(guī)范中,,我們?nèi)笔〉亩x是容器管理的事務(wù). 而且針對所有的Bean方法,應(yīng)用Required Transaction屬性,,它的意思是如果調(diào)用這個方法的應(yīng)用沒有Transaction Environment,,那么這個方法會自動創(chuàng)建一個新的。
開發(fā)人員可以使用標(biāo)注的方式在針對整個EJB或者某個具體的方法指定他的Transaction Attribute.
首先我們看一個工資處理的EJB的例子,, 這是一個標(biāo)準(zhǔn)的EJB 3.0 Stateless Session Bean,。缺省情況下,每個方法是都是由container來管理Transaction的,缺省的事務(wù)屬性是required
// Uses container-managed transction, REQUIRED attribute
@Stateless public PayrollBean implements Payroll {
public void setBenefitsDeduction(int empId, double deduction) {...}
public double getBenefitsDeduction(int empId) {...}
public double getSalary(int empId) {...}
public void setSalary(int empId, double salary) {...}
}

下面還是這個例子,,我們知道對于有關(guān)重要數(shù)據(jù)的改動,,總是非常敏感的。比如我們在更改某個用戶的工資的時候同時修改他的所得稅,,我們希望這兩個調(diào)用是在同一個Transaction里面發(fā)生的,。

@Stateless public PayrollBean implements Payroll {
@TransactionAttribute(MANDATORY)
public void setBenefitsDeduction(int empId, double deduction) {...}
public double getBenefitsDeduction(int empId) {...}
public double getSalary(int empid) {...}
@TransactionAttribute(MANDATORY)
public void setSalary(int empId, double salary) {...}
}

那么調(diào)用用戶的工資改動的方法就必須在一個已經(jīng)存在的Transaction Environment
中,為此,,我們用@transactionattribute(mandatory)標(biāo)注 這個方法必須在一個客戶端的transaction中,,如果客戶端沒有這樣的一個 Transaction Context, Container會扔出來一個 Javax.ejb.EjbTransactionRequiredException 的錯誤信息,。

 

2.5 新的安全機制
EJB架構(gòu)不鼓勵開發(fā)人員用代碼的方式實現(xiàn)安全機制,而是采用安全角色的方法,,通過定義可以訪問的安全角色,,來限制對某個方法的訪問權(quán)限。

缺省情況,,在3.0里面所有的方法都是"unchecked",。也就是說缺省情況下對所有方法是不用安全控制策略的。如果調(diào)用某個方法的客戶端具有某個用戶角色(Role) ,,我們可以制定是否這個方法也是沿用這個角色,。缺省情況下的安全策略是"Caller Identity",也就是說被調(diào)用者的角色和調(diào)用者的角色應(yīng)該是一致的

這是一個EJB 3.0的安全實現(xiàn)的例子。我們對于其他的方法都沒有設(shè)定安全策略,。但是對于設(shè)定某個員工的工資是多少,,這樣的安全要求比較高的方法設(shè)定了只有人事部門的管理員才能調(diào)用。我們采用了一個

@RolesAllowed("HR_PayrollAdministrator ")
// Security view
@Stateless public PayrollBean implements Payroll {
public void setBenefitsDeduction(int empId, double deduction) {...}
public double getBenefitsDeduction(int empId) {...}
public double getSalary(int empid) {...}
// salary setting is intended to be more restricted
@RolesAllowed( HR_PayrollAdministrator )
public void setSalary(int empId, double salary) {...}
}

2.6 事件的通知和檢查

EJB 3.0中, 開發(fā)人員不需要實現(xiàn)那些不必要的callback methods,。 他可以把任意方法指定為一個事件通知方法,。通過標(biāo)記一個通知標(biāo)注,我們把一個方法標(biāo)記為一個回調(diào)方法,, 例如:

@Stateful public class AccountManagementBean
implements AccountManagement {
Socket cs;
@PostConstruct
@PostActivate
public void initRemoteConnectionToAccountSystem {
...
}

@PreDestroy
@PrePassivate
public void closeRemoteConnectionToAccountSystem {
...
}
...
}

在這個EJB 3.0 的例子當(dāng)中,, 我們定義了一個有狀態(tài)的session Bean,把初始化的工作都交給init remote connection方法,同時標(biāo)記他為一個回調(diào)方法,在construct ,和 activite之后調(diào)用
同時我們把清理的工作都交給close remote connection方法,同時標(biāo)記他為一個回調(diào)方法,在destroy 和passivate之前調(diào)用

對于那些高級的用戶,,需要定制自己的事件檢查和偵聽機制,。檢查方法和所被檢查的對象方法可以在同一個 Bean 中,也可以在不同的JAVA Class里面。 這種檢查機制有下面的特點:
在方法周圍進行檢查
包裝商務(wù)方法的整個調(diào)用過程
可以對方法調(diào)用的參數(shù)和結(jié)果進行處理
檢查類的序列中,,可以拿到上下文數(shù)據(jù)
多個檢查類可以按照指定的順序執(zhí)行
可以用部署表述符來指定執(zhí)行順序

我們用 @Interceptors 標(biāo)注指定一個外部的檢查方法類,, 用 @AroundInvoke制定內(nèi)部的某個方法為檢查方法。在檢查方法里面,我們用proceed()來調(diào)用具體的商務(wù)方法,。目前的檢查方法是檢查一個Bean里面的所有方法,專家組正在制定標(biāo)準(zhǔn),, 讓它可以具體到檢查制定的某個方法。

下面是一個EJB3.0的檢查方法的例子:

我們制定了這個無狀態(tài)session Bean檢查方法類是這三個類.
accountaudit, metrics, customsecurity,。那么實際執(zhí)行的時候會按照這個制定的順序來實行
檢查.

@Interceptors({
com.acme.AccountAudit.class,
com.acme.Metrics.class,
com.acme.CustomSecurity.class
})
@Stateless
public class AccountManagementBean
implements AccountManagement {
public void createAccount(int accountId, Details details) {...}
public void deleteAccount(int accountId) {...}
public void activateAccount(int accountId) {...}
public void deactivateAccount(int accountId) {...}
...
}

2.7 部署描述文件的優(yōu)先級

在EJB3.0中,我們可以用標(biāo)注的方法來指定對環(huán)境對象的引用,也可以用部署描述符文件(Deployment Description)的方式來制定對環(huán)境對象的應(yīng)用, 也可以兩個同時使用. 如果我們在部署描述文件和代碼標(biāo)注中都制定了環(huán)境對象,那么部署描述文件中的那個引用有更高的優(yōu)先級, 這樣就給了應(yīng)用的Deployer相對比較大的靈活性來控制.

3 持久化的魔力


3.1 最初的目標(biāo)

EJB 3.0 專家組的另外一個目標(biāo)是為實體Bean( Entity Bean ) 和對象/關(guān)系的映射,,提供一個輕量級的模型。實際上,,目前關(guān)于實體Bean的爭論很多,, 很多批評人士對它的架構(gòu)感到不滿,我們的目標(biāo)是改善EJB 容器管理的持久化模型,,從各地的一些優(yōu)秀的開源軟件中吸取靈感,,從一些反模式(Anti-Pattern)中吸取經(jīng)驗, 從而讓新的標(biāo)準(zhǔn)稱為技術(shù)上的領(lǐng)%9

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多