wordpress增加關(guān)鍵詞寧波seo在線優(yōu)化方案
一、EJB是什么?
- EJB是sun的JavaEE服務(wù)器端組件模型,是一種規(guī)范,設(shè)計(jì)目標(biāo)與核心應(yīng)用是部署分布式應(yīng)用程序。
- EJB2.0過于復(fù)雜,EJB3.0的推出減輕了開發(fā)人員進(jìn)行底層開發(fā)的工作量,它取消或最小化了很多(以前這些是必須實(shí)現(xiàn))回調(diào)方法的實(shí)現(xiàn),并且降低了實(shí)體Bean及O/R映射模型的復(fù)雜性。
- EJB大概是J2EE架構(gòu)中唯一一個(gè)沒有兌現(xiàn)其能夠簡單開發(fā)并提高生產(chǎn)力承諾的組件。
二、EJB3.0新特性
相比EJB3以前的版本而言,增加了兩個(gè)新特性:元數(shù)據(jù)注解(Annotation) 和依賴注入(Injection),而元數(shù)據(jù)注解以最大限度的使部署描述符從冗余繁雜中脫離出來。
三、EJB體系結(jié)構(gòu)
EnterpriseBean和Serializable接口一樣,是一個(gè)標(biāo)記性接口。用于標(biāo)記一個(gè)類為一個(gè)Bean。它有三種實(shí)現(xiàn):SessionBean,EntityBean,MessageDrivenBean。
SessionBean:它是對業(yè)務(wù)邏輯的封裝,類似于我們經(jīng)常寫的Service層。它可以以local, remote, webservice 服務(wù)的方式被client調(diào)用。
EntityBean:它是對數(shù)據(jù)庫對象的封裝,一個(gè)EntityBean,就是數(shù)據(jù)庫的一條記錄。
MessageDrivenBean:一個(gè)messageDrivenBean其實(shí)就是一個(gè)javax.jms.MessageListener。在JMS中有MessageConsumer,它支持兩種接收消息的方式:同步接收采用MessageConsumer#receive()方法,異步接收則是為MessageConsumer設(shè)置一個(gè)MessageListener,一旦接收到消息,就調(diào)用listener#onMessage()。
四、SessionBean
1、SessionBean服務(wù)組件
SessionBean服務(wù)端有三大組件Home、EJbObject、SessionBean。
SessionBean是我們編寫業(yè)務(wù)邏輯的地方。譬如數(shù)據(jù)庫操作,進(jìn)行計(jì)算等等。但是它對于客戶端是不可見的,一個(gè)SessionBean實(shí)例的創(chuàng)建、銷毀、激活、鈍化等都是由EJB容器來管理的。
EJBObject:你可以將EJBObject看作是SessionBean對象的Proxy。需要將你的業(yè)務(wù)方法同樣在EJBObject中復(fù)制一份。例如有一個(gè)HelloSessionBean#sayHello(str) 業(yè)務(wù),如果要將該業(yè)務(wù)方法暴露出去給Client使用,與之對應(yīng)的HelloEJBObject中必然得包含#sayHello(str)方法。也就是說Client需要使用EJBObject來達(dá)到與SessionBean交互的。
Home:這個(gè)名字起的怪異,我們可以將其理解為一個(gè)SessionBean的Factory。EJB容器通過Home對象來創(chuàng)建SessionBean對象,并裝配出它的代理對象(EJBObject對象)。這是它的唯一用途。
2、Remote與Local
對于Home,和EJBObject,它們倆個(gè)都分為兩類:Remote,Local。
Remote模式的,主要用于不在同一個(gè)JVM進(jìn)程里,而在同一個(gè)進(jìn)程里使用時(shí),只需要使用Local模式的即可,這樣選擇自然是為了性能考慮。
3、Client訪問處理流程(很容易看出Local性能好在哪里)
3.1 Remote模式下SessionBean 的訪問流程
1、客戶端通過JNDI獲取到Home對象(EJBHome)的引用
2、客戶端使用homeRef#create()方法來創(chuàng)建出EJBObject的Stub。
2.1)客戶端底層使用Socket通信將次過程發(fā)給服務(wù)端Skeleton。
2.2)Skeleton調(diào)用服務(wù)端的Home對象的create方法,分配SessionBean對象(可能是新創(chuàng)建一個(gè),也可能是從對象池中取一個(gè),具體怎樣依賴于是否是Stateful的),同時(shí)為該SessionBean對象生成一個(gè)代理對象(EJBObject實(shí)例),然后返回代理對象的引用。
2.3)客戶端拿到EJBObject的引用就是Stub對象。
3、客戶端訪問業(yè)務(wù)
3.1) 客戶端底層使用Socket通信將次過程發(fā)給服務(wù)端Skeleton。
3.2)Skeleton根據(jù)請求找到該EJBObject,調(diào)用與之關(guān)聯(lián)的SessionBean的相應(yīng)的業(yè)務(wù)。返回結(jié)果
3.3)客戶端得到調(diào)用結(jié)果
3.2 Local模型下SessionBean的訪問流程
1、客戶端通過JNDI獲取到Home對象(EJBLocalHome)的引用
2、客戶端使用homeRef#create()方法來創(chuàng)建出EJBLocalObject(怎么創(chuàng)建也要依賴于是否的Stateful的)
3、客戶端訪問業(yè)務(wù)
五、常用注解
**@Stateless:**標(biāo)記類把Java類聲明為一個(gè)無狀態(tài)會話bean
**@EJB:**表示注入實(shí)例,EJB注入和Resource注入相比,EJB注入只是針對于EJB而言,而Resource注入即是對所有的文件都可以進(jìn)行注入。
**@Remove:**為會話 Bean 聲明遠(yuǎn)程業(yè)務(wù)接口。用在接口上時(shí),將該接口指定為遠(yuǎn)程業(yè)務(wù)接口。在這種情況下,不提供任何 value()。用在方法上,通過這個(gè)注解來說明在調(diào)用這個(gè)方法之后bean的實(shí)例將被清除掉。
**@Local:**用在 Bean 類上時(shí),為會話 Bean 聲明本地業(yè)務(wù)接口。用在接口上時(shí),將該接口指定為本地業(yè)務(wù)接口。在這種情況下,不提供任何 value()。如:@Local(LawsuitService.class)
**@Stateful:**有狀態(tài)會話 Bean 的組件定義注釋。
**@Timeout:**指定無狀態(tài)會話 Bean 類或消息驅(qū)動 Bean 類上接收該 Bean 的 EJB 計(jì)時(shí)器過期的方法。
**@TransactionAttribute:**在 TYPE-level 應(yīng)用時(shí),為會話或消息驅(qū)動 Bean 的所有業(yè)務(wù)方法指定默認(rèn)事務(wù)屬性。在方法級應(yīng)用時(shí),僅為該方法指定事務(wù)屬性。
如:@TransactionAttribute(TransactionAttributeType.SUPPORTS)、
@TransactionAttribute(TransactionAttributeType.REQUIRED)。
**@Interceptors:**聲明類或方法的攔截器的有序列表。
**@Lock:**方法聲明一個(gè)并發(fā)鎖的單例bean具有容器管理的并發(fā)。
**@Schedule(排程器):**計(jì)劃時(shí)間為自動建立一個(gè)超時(shí)計(jì)劃基于一個(gè)時(shí)間表達(dá)式。
**@Startup:**標(biāo)記一個(gè)單例在應(yīng)用初始化期間。
**@ConcurrencyManagement:**聲明單例或有狀態(tài)bean的并發(fā)管理類型
六、EJB的使用
1.依賴導(dǎo)入:
pom.xml
<dependencies> <dependency><groupId>javax</groupId><artifactId>javaee-web-api</artifactId><version>7.0</version><scope>provided</scope></dependency></dependencies>
2.代碼示例:
@Stateless
//不寫默認(rèn)本地@Localpublic class ProdMgr {@EJB//注入prodService,如果出現(xiàn)多個(gè)ProdService接口的實(shí)現(xiàn)類可以使用name屬性區(qū)分private ProdService service;public String getName() {String name = service.prod.getName();return name;}