花了一段時間下載了jboss-4.0.4.GA, jboss-EJB-3.0_RC8-FD, JBossIDE-1.5.1.GA-Bundle-win32
按照jboss-EJB-3.0_RC8-FD中install.htm中的配置指南(有問題,解決辦法見fisheye.jboss),我不是完全按照它來做的,因為我使用的是 default目錄,而沒有使用all.
一切準備好后,我先是直接在Eclipse中把Enterprise Javabean第五版中的例一跑了一遍,成功了。
接下來按照菜鳥也學EJB1,2,3,4系列(http://willbe.xinwen365.net/ejb3-4.htm )全部跑了一遍,感覺還不錯。下面是測試SLSB和SFSB區別的例子(有改動)
@Remote
public
?
interface
?Say?{
????
public
?String?say();
????
public
?@Remove?String?goodBye();
}
public
?@Stateful?
class
?SayBean?
implements
?Say?{
????
private
?
int
?i?
=
?
0
;?
//
?SayBean自己的狀態
????
public
?String?say()?{
????????i
++
;
????????
return
?
"
Hello?World!?
"
?
+
?i;
????}
????
public
?String?goodBye()?{
????????
return
?
"
bye,?bye
"
;
????}
}
public
?
class
?Client?{
????
public
?
static
?
void
?main(String[]?args)?
throws
?Exception?{
????????InitialContext?ctx?
=
?
new
?InitialContext();
????????Say?say?
=
?(Say)?ctx.lookup(
"
SayBean/remote
"
);
????????System.out.println(say.say());
????????System.out.println(say.goodBye());
????????
try
?{
????????????System.out.println(say.say());
????????}?
catch
?(RuntimeException?e)?{
????????????System.err.println(
"
goodBye?in?Stateful?sessionbean?destroys?everything!
"
);
????????????e.printStackTrace();
????????}
????}
}
當SayBean標記為@Stateful時,多次調用的結果始終相同,
因為客戶和Stateful SessionBean(有狀態會話Bean)的關系是一對一的關系,當客戶調用銷毀方法(帶@Remove標簽的方法)時,服務器就會銷毀該對象,即使注釋掉最后一句——不調用銷毀方法,系統依然會銷毀該有狀態會話Bean.
另外,如果顯示調用它的銷毀方法后試圖重新使用它的時候就拋出異常:javax.ejb.EJBNoSuchObjectException: Could not find Stateful bean(這里留一個問題,我上面的代碼怎么沒有拋出異常?)
當SayBean標記為@Stateless時,每次調用的結果都不同,因為客戶和Stateless SessionBean(無狀態會話Bean)的關系是多對一的關系,即使每次調用后say.say()后均調用它的銷毀方法say.goodBye(),系統也不會銷毀無狀態會話Bean.
還有一個送玫瑰和介指的例子,和這個大同小異。
今天,你給消息驅動了嗎?
@MessageDriven(activationConfig?
=
?{
????@ActivationConfigProperty(propertyName?
=
?
"
destinationType
"
,?propertyValue?
=
?
"
javax.jms.Queue
"
),
????@ActivationConfigProperty(propertyName?
=
?
"
destination
"
,?propertyValue?
=
?
"
queue/mytest/test
"
)?})
public
?
class
?TestDriven?
implements
?MessageListener?{
????
public
?
void
?onMessage(Message?arg0)?{
????????System.out.println(
"
我是中國第一個玩EJB3菜鳥級人物!
"
);
????}
}
我們的TestDriven類實現了MessageListener接口,所以,我們有理由相信他就是一個監聽器.,原來消息驅動Bean是一個監聽器哦~_~. 我們還看到了一個onMessage方法, 這個不就是我們的onClick() onEnter() onClose()等等on系列的兄弟嗎? 他怎么升級了,跑到j2ee里面去了.呵呵,看來我們的onClick(),onEnter()等兄弟們要加倍努力呀.看看那sun公司肯不肯也收留我們這幫兄弟.我們還看到了@MessageDriven這個東東,嗯,原來這是個老大來的,他說得算,如果沒有他,這個TestDriven就不是MessageDrivenBean(消息驅動Bean)了..
好吧,我們先不管三七二十一,寫些東東到方法onMessage(Message arg0)里面,看看有沒有什么不良反映(~_~看他會不會吃錯藥).. 那就加個 System.out.println(“我是中國第一個玩EJB3菜鳥級人物”);
public
?
class
?Client?{
????
public
?
static
?
void
?main(String[]?args)?
throws
?Exception?{
????????QueueConnection?cnn?
=
?
null
;
????????QueueSender?sender?
=
?
null
;
????????QueueSession?session?
=
?
null
;
????????
//
?創建上下文環境,這個是什么東東,呵呵,我們以前談過了.
????????InitialContext?ctx?
=
?
new
?InitialContext(ht);
????????
//
?該參數為驅動該TestDriven的隊列,我們后面會詳細說明
????????Queue?queue?
=
?(Queue)?ctx.lookup(
"
queue/mytest/test
"
);
????????
//
?這位大哥可真貪心,lookup了驅動隊列,還要lookup隊列的連接工廠..還是有點復雜喲!我的消息驅動Bean兄弟
????????QueueConnectionFactory?factory?
=
?(QueueConnectionFactory)?ctx
????????????????.lookup(
"
ConnectionFactory
"
);
????????
//
?創建隊列連接
????????cnn?
=
?factory.createQueueConnection();
????????
//
?由連接創建回話
????????session?
=
?cnn.createQueueSession(
false
,?QueueSession.AUTO_ACKNOWLEDGE);
????????
//
?把字符串打包成一個消息
????????TextMessage?msg?
=
?session.createTextMessage(
"
Hello?World
"
);
????????
//
?由回話(session)創建到目標驅動隊列的發送者
????????sender?
=
?session.createSender(queue);
????????
//
?發射,呵呵,神州六號好像也是這樣發送的吧.
????????sender.send(msg);
????????
//
?開始得意洋洋了.~_~
????????System.out.println(
"
我已經成功地驅動了那個鳥人(消息驅動Bean)!
"
);
????}
}
看到順序了嗎:? 首先通過ctx 從jndi大哥那里偷到ConnectionFactory(連接工廠)這個寶貝,然后那,然后由我們的連接工廠去創建連接,然后由連接創建回話,然后由回話根據目標隊列創建發送者,然后就發送吧.
??? 呵呵,暈了吧,其實那個東東是所謂的那些牛人寫了一本叫做<<設計模式>>的書,剛才那里的代碼就是他里面說的典型的工廠模式. 反正呢. 以為,我們的代碼要依賴于jndi大哥,所以只能這位大哥說得算,你用new去創建對象,人家大哥就不同意,他會覺得沒面子.呵呵.(說笑)..
最后是一個queue-service.xml的文件,布署的時候要放到deploy目錄下,JBoss自動檢測到這個不知道什么東西的文件,然后打印出[mytest] Bound to JNDI name: queue/mytest/test,原來這個文件就是叫JBoss服務器去幫定一個隊列queue/mytest/test,這樣然后在客戶端就可以用 Queue queue = (Queue) ctx.lookup("queue/mytest/test")從InitialContext把它取出來
<?
xml?version="1.0"?encoding="UTF-8"
?>
<
server
>
?
<
mbean?
code
="org.jboss.mq.server.jmx.Queue"
??name
="jboss.mq.destination:service=Queue,name=mytest"
>
??
??
<
attribute?
name
="JNDIName"
>
queue/mytest/test
</
attribute
>
??
??
<
depends?
optional-attribute-name
="DestinationManager"
>
???jboss.mq:service=DestinationManager
</
depends
>
??
?
</
mbean
>
</
server
>
更多關于使用EJB3的東東有待繼續看書看例子,之后我會陸續寫或轉載些東西,盡請關注