JavaBean編程應(yīng)用技術(shù)
Java語言的組件技術(shù) ;
JavaBean設(shè)計目標及其實現(xiàn)手段;
JavaBean中的屬性;
JavaBean的事件及自定義事件;
JavaBean持久化
JavaBean的自檢
JavaBean的編程實例
一、Java語言的組件技術(shù)
1、JavaBean是什么?
(1)Bean是一個特殊的類,這個類必須符合JavaBean規(guī)范(是一個非常簡單的遵循某種嚴格協(xié)議的Java類)。
(2)JavaBean是用Java語言編寫的可重用軟件組件。
2、Bean的種類:
可視化軟件組件:可以是簡單的GUI元素,如按鈕或滾動條;也可以是復(fù)雜的,如數(shù)據(jù)庫視圖
非可視化軟件組件:沒有GUI表現(xiàn)形式,用于封裝業(yè)務(wù)邏輯、數(shù)據(jù)庫操作等
3、JavaBean與微軟的ActiveX的不一樣
JavaBean是與平臺無關(guān)的
ActiveX是基于Windows系統(tǒng)平臺的
4、JavaBean組件與EJB的不同:
JavaBean組件存儲狀態(tài)信息
EJB組件存儲業(yè)務(wù)邏輯
5、Bean的應(yīng)用場合:
在使用Java編程時,并不是所有軟件模塊都需要轉(zhuǎn)換成Bean。
Bean比較適合于那些具有可視化操作和定制特性的軟件組件。
6、JavaBean的開發(fā)方法:
采用可視化開發(fā)工具---主要有:
Borlands公司的JBuilder
SunSoft的Java Studio
Symantec的Visual Café
IBM的Visual Age for Java等;
當然也可以手寫代碼。
7、JavaBean的編程要點:
一個Bean不必非要繼承特定的基類或接口;
可視化的Bean必須繼承的類是Component類,這樣它們才能添加到可視化容器中去;
非可視化Bean則不需要繼承這個類。
一個Bean本質(zhì)上就是一個Java類的代碼,只是添加了所謂的自檢和序列化,因此Bean實際就是一個普通的Java類。
二、JavaBean設(shè)計目標及其實現(xiàn)手段
(1)緊湊而方便的創(chuàng)建和使用
因為Bean組件常常用于分布式計算環(huán)境中,這使得JavaBean組件常常需要在有限的帶寬連接環(huán)境下進行傳輸。
顯然,為了適應(yīng)傳送的效率和速度,JavaBean組件必須是越緊湊越好。
(2)完全的可移植性
JavaBean API與獨立于平臺的Java系統(tǒng)相結(jié)合,提供了獨立于平臺的組件解決方案。因此,組件開發(fā)者就可以不必再為帶有JavaBean平臺特有的類庫而擔心了。
最終的結(jié)果都將是計算機界共享可重復(fù)使用的組件,并在任何支持Java的系統(tǒng)中無需修改地執(zhí)行
(3)繼承Java的強大功能
現(xiàn)有的Java結(jié)構(gòu)已經(jīng)提供了多種易于應(yīng)用于組件的功能。其中一個比較重要的是Java本身的內(nèi)置類發(fā)現(xiàn)功能,它可以使得對象在運行時彼此動態(tài)地交互作用,這樣對象就可以從開發(fā)系統(tǒng)或其開發(fā)歷史中獨立出來。
JavaBean繼承在現(xiàn)有Java功能中還有一個重要的方面,就是持久性,它保存對象并獲得對象的內(nèi)部狀態(tài)。
通過Java提供的序列化(serialization)機制,持久性可以由JavaBean自動進行處理。
當然,在需要的時候,開發(fā)者也可以自己建立定制的持久性方案。
三、一個簡單的JavaBean程序代碼
import java.awt.*;
import java.io.Serializable;
public class JavaBeanButton extends Canvas implements Serializable
{ //任何實現(xiàn)了Serializable接口的Java類都可以成為一個JavaBean類。
public JavaBeanButton()
{ this.setSize(50,50);
}
public void paint(Graphics g)
{ g.setColor(Color.LIGHT_GRAY);
g.fillOval(0,0,50,50);
}
}
JavaBean程序結(jié)構(gòu)要點
1、可視化的Bean應(yīng)該從Component或者Canvas類來繼承
2、每個Bean應(yīng)該實現(xiàn)Serializable接口
3、JavaBean中的構(gòu)造函數(shù)
每個JavaBean的類中應(yīng)該提供一個不帶參數(shù)的默認構(gòu)造函數(shù),以便構(gòu)造工具能夠?qū)嵗鋵ο蟆.斎贿€應(yīng)該有帶參數(shù)的構(gòu)造函數(shù)以便能夠?qū)λM行初始化。
4、其它則與一般的Java類的編程規(guī)則相同
四、JavaBean的存儲格式
Jar文件:
JavaBean組件被設(shè)計出來后,一般是以擴展名為jar的格式文件存儲,在jar中包含與JavaBean有關(guān)的信息,并以MANIFEST文件指定其中的哪些類是JavaBean。
Jar文件中的manifest文件的內(nèi)容如下:
Name: JavaBean.class
Java-Bean: True
利用Jar命令產(chǎn)生*.jar文件。命令格式如下
C> jar cfm JavaBean.jar JavaBeanManifest.txt JavaBean.class
參考JavaBeanStepbyStep中的step1
五、JavaBean中的屬性
JavaBean的屬性與一般Java程序中所指的屬性,或者說與所有面向?qū)ο蟮某绦蛟O(shè)計語言中對象的屬性是一個概念,在程序中的具體體現(xiàn)就是類中的變量。在JavaBean的設(shè)計中,按照屬性的不同作用又細分為四類:
單值屬性
索引屬性
關(guān)聯(lián)屬性
限制屬性
屬性一、JavaBean中的單值屬性
(1)含義:它表示一個伴隨有一對get/set方法的變量。屬性名與和該屬性相關(guān)的get/set方法名對應(yīng)。
(2)編碼規(guī)則
屬性聲明為私有,沒有公有的屬性
通過訪問方法而不是直接存儲實例變量
屬性值xxx對應(yīng)有g(shù)etXxx和setXxx方法
對于布爾型的屬性,可以用isXxx方法查值
Bean的普通方法不適合上面的命名規(guī)則,但它們是公有的。
JavaBean中的單值屬性示例代碼
public class myCanvas extends Canvas implements Serializable
{
String ourString= "Hello"; //屬性名為ourString,類型為字符串
boolean editable; public myCanvas()
{ setBackground(Color.red);
setForeground(Color.blue); }
public void setOurString(String newString)
{ /* “set”屬性*/
ourString=newString; } public String getOurString()
{ /* "get"屬性 */
return ourString; }
public boolean isEditable()
{ /* "布爾"屬性 */
return editable; }
}
屬性二、JavaBean中的索引屬性
含義:
它表示一個數(shù)組值。使用與該屬性對應(yīng)的set/get方法可取得數(shù)組中的成員數(shù)據(jù)值(需要有一個整數(shù)索引參數(shù))或者一次設(shè)置或取得整個數(shù)組的值。
索引屬性的設(shè)計模式如下:
(1)訪問整個索引屬性數(shù)組的方法
public
public void set
(2)訪問整個索引屬性中的單個值的方法
public
public void set
JavaBean中的索引屬性示例代碼
public class myCanvas extends Canvas implements Serializable
{ int[] dataSet={1,2,3,4,5,6}; //dataSet是一個索引屬性 public myCanvas()
{ setBackground(Color.red);
setForeground(Color.blue); }
public void setDataSet(int[] newdataSet)//設(shè)置整個數(shù)組
{ dataSet= newdataSet; } /* 設(shè)置數(shù)組中的單個元素值 */
public int[] getDataSet() /* 取得整個數(shù)組值 */
{ return dataSet; }
public void setDataSet(int index, int x)
{ dataSet[index]=x; } public int getDataSet(int index)
{ /* 取得數(shù)組中的指定元素值 */
return dataSet[index]; }
}
屬性三、JavaBean中的關(guān)聯(lián)屬性
含義:
它是指當該種屬性的值發(fā)生變化時,要通知其它的對象。
每次的屬性值改變時,這種屬性就點火一個PropertyChange事件。
事件中封裝了屬性名、屬性的原值、屬性變化后的新值。
至于接收事件的Bean應(yīng)做什么動作由其自己定義。
包含關(guān)聯(lián)屬性的Bean必須具有以下的功能:
允許事件監(jiān)聽器注冊和注銷與其有關(guān)的屬性修改事件;
當修改一個關(guān)聯(lián)屬性時,可以在相關(guān)的監(jiān)聽器上觸發(fā)屬性修改事件。
在java.beans包中利用PropertyChangeSupport類創(chuàng)建出該類的對象,從而可以用于管理注冊的監(jiān)聽器列表和屬性修改事件通知的發(fā)送。
關(guān)聯(lián)屬性的編程要點
1、由于當關(guān)聯(lián)屬性被改變時,將使用PropertyChangeSupport類中的firePropertyChange方法來點火屬性改變事件。
2、應(yīng)該存儲關(guān)聯(lián)屬性的原始屬性值,因為屬性值和新的屬性值都要傳給firePropertyChange()方法,而且它們都是Object類型。因此如果為基本的數(shù)據(jù),則應(yīng)該轉(zhuǎn)換為對應(yīng)的類類型。
3、屬性修改事件是在屬性被修改后觸發(fā)。
changes.firePropertyChange("ourString",oldString,newString);
4、Bean要預(yù)留出一些接口給開發(fā)工具,開發(fā)工具使用這些接口,把其它的JavaBean對象與該Bean相掛接。
public void addPropertyChangeListener(PropertyChangeListener listener)
{changes.addPropertyChangeListener(listener);}
public void removePropertyChangeListener(PropertyChangeListener listener)
{changes.removePropertyChangeListener(listener);}
屬性四、JavaBean中的限制屬性
含義:
它指當這個屬性的值要發(fā)生變化時,與這個屬性已建立了某種連接的其它外部Java對象可否決該屬性值的改變;
當然Bean 本身也可以否決該Bean屬性值的改變。
如何限制屬性: 限制屬性的監(jiān)聽者通過拋出PropertyVetoException來阻止該屬性值的改變。
監(jiān)聽者:限制屬性一般有兩種監(jiān)聽者
屬性變化監(jiān)聽者
否決屬性改變的監(jiān)聽者
否決屬性改變的監(jiān)聽者在自己的對象代碼中有相應(yīng)的控制語句,在監(jiān)聽到有限制屬性要發(fā)生變化時,在控制語句中判斷是否應(yīng)否決這個屬性值的改變
限制屬性的編程要點
1、分別聲明PropertyChangeSupport和VetoableChangeSupport類的對象(限制屬性值可否改變 )
2、當屬性被改變時,然后點火屬性改變否決事件。
vetos.fireVetoableChange(…);
3、若有其它對象否決屬性的改變,則程序拋出異常,不再繼續(xù)執(zhí)行下面的語句,方法結(jié)束。若無其它對象否決屬性的改變,則把該屬性賦予新值,并點火屬性改變事件。
4、與屬性改變事件相同,也要為限制屬性預(yù)留接口,使其它對象可注冊入限制屬性的否決改變監(jiān)聽者隊列中,或把該對象從中注銷。
5、限制屬性實際上是一種特殊的關(guān)聯(lián)屬性,只是它的值的變化可以被監(jiān)聽者否決掉。
public void addVetoableChangeListener(VetoableChangeListener listener)
{
vetos.addVetoableChangeListener(listener); } public void removeVetoableChangeListener(VetoableChangeListener listener)
{
vetos.removeVetoableChangeListener(listener); }
六、JavaBean的事件編程
1、通過事件處理機制
可讓一些組件作為事件源,發(fā)出可被描述環(huán)境或其它組件接收的事件。
這樣,不同的組件就可在構(gòu)造工具內(nèi)組合在一起,組件與組件、組件與外界之間通過事件的傳遞進行通信,構(gòu)成一個應(yīng)用。
2、JavaBean事件模型的總體結(jié)構(gòu)(略)
3、事件監(jiān)聽者的注冊與注銷
為了各種可能的事件監(jiān)聽者把自己注冊入合適的事件源中,建立源與事件監(jiān)聽者間的事件流,事件源必須為事件監(jiān)聽者提供注冊和注銷的方法。
public void add< ListenerType> (< ListenerType> listener);
public void remove< ListenerType> (< ListenerType> listener);
4、事件編程的步驟
聲明指定的事件接口對象
允許觸發(fā)該類型的事件
實現(xiàn)維護該事件的監(jiān)聽器列表的方法(應(yīng)該包含有添加和刪除)
向所有注冊該類型的事件組件分發(fā)該事件
七、JavaBean 的自檢
(1)含義:
使外部組件能夠?qū)ふ业疥P(guān)于JavaBean的結(jié)構(gòu)和功能的內(nèi)部信息。
(2)方法:
利用設(shè)計模式來隱含地提供自檢信息。
由于Bean中的屬性、方法、事件等的命名有一定的規(guī)則,外部系統(tǒng)可以利用這些規(guī)則來獲得Bean的結(jié)構(gòu)和功能的內(nèi)部信息。
屬性設(shè)計模式
事件設(shè)計模式
方法設(shè)計模式
利用BeanInfo提供顯示信息
1、利用屬性設(shè)計模式提供自檢信息
屬性設(shè)計模式:
用于標識Bean 中的公有的可訪問的屬性,即依賴getXXX()、setXXX()、isXXX()等訪問者方法來決定可訪問的屬性。
2、利用事件設(shè)計模式提供自檢信息
事件設(shè)計模式:
Bean將事件通知發(fā)送給需要接收這些通知并已經(jīng)在這個Bean上注冊了的事件監(jiān)聽器。
因為事件監(jiān)聽器必須在Bean上進行注冊,所以需要Bean提供適當?shù)姆椒▉韺崿F(xiàn)注冊過程。
因為在JavaBean的自檢機制中,可以從注冊方法的名字以及方法的參數(shù)類型檢測到事件源會產(chǎn)生什么事件。
事件設(shè)計模式編程要點
事件注冊方法常常是成對出現(xiàn)(添加和刪除)。
JavaBean的自檢器正是使用這些方法訪問Bean可以發(fā)送的事件。
事件注冊必須遵循如下的事件設(shè)計模式,以便自動自檢服務(wù)可以正確地進行
public void add
public void remove
3、利用方法設(shè)計模式提供自檢信息
由于這些public方法是完全由Bean的設(shè)計者定義的,它們在各個Bean中沒有固定的使用特征,因此對這些方法沒有特定的設(shè)計模式要遵循。
要求:
Bean可以在一個單獨的相關(guān)類中顯示地表現(xiàn)它的特征,這個類應(yīng)該實現(xiàn)BeanInfo接口或是繼承SimpleBeanInfo類來顯示地表現(xiàn)可以被構(gòu)造器工具獲取的Bean的設(shè)計環(huán)境信息。
編程的方法:
將Bean的相關(guān)信息類的名稱后加“BeanInfo”
繼承SimpleBeanInfo類(它實現(xiàn)了BeanInfo接口)
在Bean的相關(guān)信息類中實現(xiàn)所需要的BeanInfo接口中的方法以顯式地提供Bean的信息。
import java.beans.*;
public class JavaBeanButtonBeanInfo extends SimpleBeanInfo
{ public Image getIcon(int iconKind)
{//以下代碼為JavaBean提供16*16和32*32的圖標
}
public BeanDescriptor getBeanDescriptor()
{//以下代碼為JavaeBean提供在應(yīng)用程序的構(gòu)造工具中的顯示名稱字串
}
public PropertyDescriptor[] getPropertyDescriptors()
{ //以下代碼顯式地聲明屬性
}
public int getDefaultPropertyIndex()
{ return 5;//將某個屬性作為缺省的屬性
}
public EventSetDescriptor[] getEventSetDescriptors()
{ //為Bean顯式地注冊事件接口
}
}
八、JavaBean持久化
含義: 通過持久化,可以將Bean的內(nèi)部狀態(tài)(某些字段的信息)保存下來并備以后使用。
實現(xiàn)機制:
Bean的持久化是基于Java的對象序列化機制的。因此在定義Bean時要使它實現(xiàn)Serializable接口。
存儲位置:可以存儲在文件中。 要點:
任何實現(xiàn)了Serializable接口的Java類都可以成為一個JavaBean類。
JavaBean持久化的形式
(一)默認的序列化:
實現(xiàn)了Serializable序列化接口的Bean中字段的信息將被自動保存。
若不想保存某些字段的信息則可在這些字段前冠以transient或static關(guān)鍵字
transient和static變量的信息是不可被保存的。因為transient代表Bean在某次特定會話期間的信息,是臨時變量,沒有必要永久保存。
默認的序列化編程要點
(1)一個Bean中所有public屬性都應(yīng)當是被保存的,也可有選擇地保存內(nèi)部狀態(tài)。
(2)Bean開發(fā)者在修改軟件時,可以添加字段、移走對其它類的引用,改變一個字段的private/protected/public狀態(tài),這些都不影響類的存儲結(jié)構(gòu)關(guān)系。
(3)實現(xiàn)了Serializable序列化接口的類必須有一個無參數(shù)的構(gòu)造函數(shù),重建對象時需要調(diào)用它。
(4)當從類中刪除一個字段,改變一個變量在類體系中的位置,把某個字段改成transient/static,或原來是transient/static,現(xiàn)改為別的特性時,都將引起存儲關(guān)系的變化。
(5)如果Bean的基類已經(jīng)實現(xiàn)了序列化接口,則該Bean可以不必再實現(xiàn)它。
(二)對默認的序列化進行定制,在Bean類中重寫readObject()與writeObject()方法定制序列化的數(shù)據(jù)。
如果在可序列化的Bean中包含有上面兩個方法,則可以實現(xiàn)定制序列化
應(yīng)用場合:
希望對序列化的過程執(zhí)行更多的控制(選擇性地進行序列化)。
序列化不能由默認的序列化完成的數(shù)據(jù)如static數(shù)據(jù)
或者需要向序列化數(shù)據(jù)中添加不是對象數(shù)據(jù)成員的數(shù)據(jù)時(附加的數(shù)據(jù))。
但要求它們?yōu)閜rivate方法。
定制序列化的示例代碼
private void writeObject(ObjectOutputStream out) throws IOException
{ out.defaultWriteObject();
//先進行默認的序列化寫操作
out.writeInt(JavaBeanButtonVersion );
//再寫入static 的JavaBeanButtonVersion數(shù)據(jù)
}
private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException
{ in.defaultReadObject();
//先進行默認的序列化讀操作
JavaBeanButtonVersion =in.readInt();
//再讀出static 的JavaBeanButtonVersion數(shù)據(jù)
}

posted on 2007-08-30 16:10 夏雪 閱讀(706) 評論(1) 編輯 收藏 所屬分類: Java基礎(chǔ)研究