Trang 234
Chng 12: EJB (ENTERPRISE JAVA BEANS)
Chng này ta s nghiêm cu và xây dng mt trong nhng thành phn thú v ca
java ó là JavaBean mt mô hình quan trng trong kin trúc ca Java.
Các vn chính sc cp trong chng này
JavaBean và công ngh phn mm
Tìm hiu các thành phn ca JavaBean
Tìm hiu b phân tích Introspector ca java
Xây dng và s dng JavaBean
Tích hp JavaBean vi các công ngh thành phn khác
I. Tng quan v JavaBean
JavaBean là mt công ngh lp trình hng thành phn ca Sun da trên nn tng
a ngôn ng Java. JavaBean là mt giao din lp trình dùng to ra nhng khi mã xây
ng sn và có th dùng li c. Nhng thành phn JavaBean có thc “nhúng” vào
t ng dng, liên kt vi thành phn JavaBean khác hay c dùng kt ni vi các
ng dng. Bng cách s dng JavaBean các nhà phát trin ng dng có th gim khi
ng mã mà h phi vit. H có th t vit ra chúng hoc có th mua li ca mt hãng
phát trin th ba khác (third party).
JavaBean thc cht là mt lp Java nh các lp Java thông thng khác, nhng nó
c vit theo mt quy tc quy nh trc, Bn không cn phi vit thêm bt c mã
ph nào hay s dng nhng m rng ngôn ngc bit nào to ra mt Bean.
u duy nht bn phi làm hi sa cách t tên cho các phng thc ca mình.
Chính tên phng thc mi báo cho công c xây dng bit ây có là mt thuc tính
hay mt s kin hay ch là mt phng thc thông thng.
II. Xây dng thành phn JavaBean
Nhã gii thiu trên JavaBean thc cht là mt lp java thông thng. Nh vy
t JavaBean cng có các thuc tính và các phng thc. Mt câu hi bn t ra là làm th
nào ngi dùng Bean ca bn có th bit c trong Bean ó có nhng thuc tính,
phng thc nào, kiu ca chúng ra làm sao? u này ã c các nhà thit k java gii
quyt mt cách rt n gin. bit c các thuc tính và các phng thc ca mt Bean
n ch cn tuân th theo quy tc t tên sau:
i mt thuc tính có tên là xxx, thì bn to ra hai phng thc: getXxx() và setXxx().
u ý rng ký t th nht sau “get” hay “set” phi vit hoa. Kiu tr v ca phng
thc “get” cng chính là kiu ca i phng thc “set” và thng thì chúng cng là
kiu ca thuc tính xxx. Bn cng chú ý cho là tên ca thuc tính và kiu cho “get” và
“set” là không liên quan.
i mt thuc tính boolean, bn có th dùng cách tip cn “get” và “set” trên, nhng
n cng có th dung “is” thay cho “get”.
Các phng thc thông thng ca Bean không tuân theo quy tc trên, nhng chúng
phi là phng thc public.
u Bean cho phép ng ký thính gi thì vi mt thính gi (listener) XxxListener bn
phi có hai phng thc tng ng i kèm là addXxxListener(XxxListener) và
Trang 235
removeXxxListener(XxxListener). Phn ln các bin c và thính gi là có sn bn có
th t to ra các bin c và thính gi riêng ca mình.
1. Thuc tính ca Bean
Thuc tính thc cht là mt bin nm bên trong mt lp, thông thng các thuc
tính thng c t mc truy cp là private. truy cp n các thuc tính private này ta
thng dùng hai phng thc: “get” mang ngha là ly giá tr ca thuc tính và “set” hàm
ngha gán giá tr cho thuc tính. Ví d vi mt Bean n gin có tên là xBean nh sau:
public class xBean
{
private String myName;
public String getName() { return myName;}
public void setName(String newName) { myName=newName;}
}
Thuc tính myName trong lp xBean c ly và gán gián tr thông qua phng
thc getName và setName. Nh bn thy gia tên thuc tính và tên phng thc “get” và
“set” là không liên quan n nhau. Khi B phân tích (Instrospector) ca java thy trong
Bean có hai phng thc tên là getName và setName nó s hiu rng bên trong Bean này
có mt thuc tính tên là name (vì có hai phng thc tên là getName và setName).
Ví d: Trình bày cách to ra các thuc tính và cách xây dng các phng thc “get” và
“set”
public class Bean1 {
private String str; // thuc tính kiu String
private int i; // thuc tính kiu int
private int[] arr; // thuc tính kiu mng int
private boolean b; // thuc tính kiu logic
private float f; // thuc tính kiu float
private java.io.DataInputStream is; // thuc tính kiu i tng
private java.io.DataOutputStream os;
public String getStr() { //Phng thc get cho thuc tính str
return str;
}
public void setStr(String str) { //Phng thc set cho thuc tính str
this.str = str;
}
public int getI() { //Phng thc get cho thuc tính i
return i;
}
public void setI(int i) { //phng thc set cho thuc tính i
this.i = i;
}
//Phng thc get cho thuc tính arr thuc tính này là mt //mng nên giá tr tr v là mt
ng
public int[] getArr() { return arr; }
//Phng thc set cho thuc tính arr, thuc tính này là mt //mng nên tham s là mt
ng
public void setArr(int[] arr) { this.arr = arr; }
Trang 236
//Phng thc get cho thuc tính b, do thuc tính này kiu //logic nên bn có th s dng
is thay cho get
public boolean isB() { return b; }
public void setB(boolean b) { this.b = b; }
public float getF() { return f; }
public void setF(float f) { this.f = f; }
//nu thuc tính là mt i tng thì phng thc get tr //v mt i tng kiu i
ng
public java.io.DataInputStream getIs() { return is; }
public void setIs(java.io.DataInputStream is) { this.is = is; }
public java.io.DataOutputStream getOs() { return os; }
public void setOs(java.io.DataOutputStream os) { this.os = os; }
}
a) Các thuc tính th hin s thay i (Bound Property)
JavaBean là các thành phn riêng bit nhng nó vn có th tng tác vi các i
ng khác thông qua c ch truyn thông p (message). Khi mt thuc tính ca mt
Bean A thay i nó có th thông báo cho các i tng khác bit là thuc tính ca A ã
thay i i tng này thc hin công vic gì ó chng hn nh cp nht li giá tr ca
nó theo thuc tính ca A.
ch cài t mt thuc tính có th thông báo cho các i tng khác bit khi nó
thay i rt n gin ch cn cài t hai phng thc dùng ng ký và loi b mt
i tng listener nh sau:
public void add<PropertyName>Listener(PropertyChangeListener lst)
public void remove<PropertyName>Listener(PropertyChangeListener lst)
Ví d: n có mt JavaBean A có mt thuc tính size cho bit kích c gì ó. Khi thuc tính
size thay i các i tng khác u bit s thay i này ta cài t nh sau:
public class BeanA
{float size;
private PropertyChangeSupport changeSize=new PropertyChangeSupport(this);
public void addSizeListener(PropertyChangeListener lst){}
public void removeSizeListener(PropertyChangeListener lst){}
}
Các i tng mun nhn c thông báo t JavaBean này u phi cài t giao
din PropertyChangeListener , sau ó ng ký vi thành phn BeanA nh các phng
thc mà bn xây dng bc trên. Phng thc duy nht mà bn phi ghi è khi cài t
giao din PropertyChangeListener là public void propertyChange(PropertyChangeEvent
evt) {..}
Các th tc trên ây ch thc hin nhim vng ký và to i tng Listener mà
thôi. các i tng Listener này có th nhn bit c s thay i ca thuc tính size ta
phi gi phng thc firePropertyChange ca i tng PropertyChangeSupport t thành
phn BeanA nh sau:
public void firePropertyChange (String propertyName, Object oldValue, Object
newValue)
Phng thc này s thông báo n mi i tng listener (bng cách gi phng
thc propertyChange ca listener) ã ng ký vi thành phn JavaBean. S thay i bao
Trang 237
m giá tr trc khi thay i (oldValue) và giá tr sau khi thay i (newValue) và tên
thuc tính c thay i.
Di ây là cài t lp BeanA và mt lp th nghim thuc tình nhn bit s
thay i size
//BeanA.java
import java.beans.*;
public class BeanA {
//Khai báo thuc tính size
private float size;
// changeSize có nhim v qun lý các i tng listener ã ng //ký và gi thông báo
n chúng mi khi thuc tính size thay i
PropertyChangeSupport changeSize = new PropertyChangeSupport(this);
public float getSize() { return size; }
//Phng thc gán giá tr cho cho thuc tính size
public void setSize(float newSize) {
float oldSize = size; size = newSize;
//Nu có thay i v kích thc thì thông báo n tt c các i //tng ã ng ký lng
nghe
if(oldSize!=newSize)
changeSize.firePropertyChange("size", new Float(oldSize), new Float(newSize));
}
public void addSizeListener(PropertyChangeListener lst) {
changeSize.addPropertyChangeListener(lst);
}
public void removeSizeListener(PropertyChangeListener lst) {
changeSize.removePropertyChangeListener(lst);
}
}
Ví d sau th nghim BeanA va cài t trên
// TestBeanA.java
import java.beans.*;
public class TestBeanA {
public static void main(String[] args) {
// to ra mt i tng BeanA
BeanA ba = new BeanA();
//ng ký i tng lng nghe vi i tng ba
ba.addSizeListener(new MyListener());
//thay i giá tr ca thuc tính size
ba.setSize(333);
} }
//To ra i tng có kh nng lng nghe s thay i ca thuc tính
class MyListener implements PropertyChangeListener {
//Phng thc duy nht cn phi cài t, phng thc này //c triu gi mi khi
thuc tính thay i
public void propertyChange(PropertyChangeEvent evt) {
float oldSise = ( (Float) evt.getOldValue()).floatValue();
float newdSise = ( (Float) evt.getNewValue()).floatValue();
String propertyName = evt.getPropertyName();
Trang 238
System.out.println("Change " + propertyName + " old value " + oldSise +
" new value " + newdSise);
}
}
t qu khi chy chng trình nh sau:
Change size old value 1.0 new value 333.0
Chú ý:
Trong ví d trên tên ca phng thc dùng ng ký là addSizeListener và tên ca
phng thc dùng g bng ký là removeSizeListener tuy nhiên bn có tht
cho nó mt cái tên thu thích chng hn nh dangKyLangNghe ng ký i
ng lng nghe hay huyBoLangNghe hu bi tng lng nghe.
Các i tng s không bit n s thay i ca thuc tính size cho n khi bn gi
phng thc firePropertyChange ca i tng PropertyChangeSupport.
b) Các thuc tính ràng buc (Constrain Property)
Hn ch ca các thuc tính bound trên là các i tng ch phn ng li khi giá tr
a thuc tính ã b thay i. Java cung cp mt kh nng khác mnh hn ó là to ra các
thuc tính b ràng buc (constrain property). Tng t nh thuc tính bound mi khi thuc
tính constrain nh thay i giá tr (ch dnh ch cha thay i) nó s thông báo n tt
các i tng ang lng nghe. i tng lng nghe có th t chi s thay i và nh vy
giá tr ca thuc tính vn gi nguyên giá tr ban u. Ngc li nu tt c các i tng
ng nghe u không phn i s thay i thì lúc ó thuc tính này mi nhn c giá tr
i.
mt thuc tính có th thông báo cho các i tng khác bit khi nó sp thay i
giá tr rt n gin bn ch cn cài t hai phng thc dùng ng ký và loi b
t i tng listener nh sau:
public void add<PropertyName>Listener(VetoableChangeListener lst)
public void remove<PropertyName>Listener(VetoableChangeListener lst)
Các i tng mun nhn c thông báo t JavaBean này u phi cài t giao
din VetoableChangeListener, sau ó ng ký, loi vi thành phn BeanA nh các
phng thc mà bn xây dng bc trên. Phng thc duy nht mà bn phi ghi
è khi cài t giao din VetoableChangeListener là
public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException
{.. }
i tng lng nghe không ng ý cho thay i thuc tính nó ch cn ném ra mt
ngoi l PropertyVetoException, thành phn JavaBean có thuc tính constrain s bt
y và hu b vic thay i giá tr cho thuc tính.
ng nh thuc tính bound, khi thuc tính constrain có dnh thay i giá tr trong
phng thc “set” nó cn thông báo n các i tng ã ng ký lng nghe
(listener) vi nó bng phng thc fireVetoableChange ca i tng
VetoableChangeSupport t thành phn JavaBean nh sau:
public void fireVetoableChange (String propertyName, Object oldValue, Object
newValue)
Trang 239
Phng thc này s thông báo n mi i tng listener (bng cách gi phng
thc vetoableChange ca listener) ã ng ký vi thành phn JavaBean.
Nhn xét: i tng VetoableChangeSupport cng tng t nh i tng
PropertyChangeSupport dùng qun lý các i tng listener. PropertyChangeSupport
c dùng vi các thuc tính bound còn VetoableChangeSupport dùng cho thuc tính
constrain.
i ây là mt cài t cho mt JavaBean B có thuc tính size. Mi khi size thay i nó s
thông báo cho các thành phn khác bit thông qua i tng listener. i tng listener
này s t chi không cho thay i nu size >100.
// BeanB.java
import java.beans.*;
public class BeanB {
//Khai báo thuc tính size
private int size = 0;
// vetoAgent vó nhim v qun lý tt c các i tng listener //ã ng ký
private VetoableChangeSupport vetoAgent = new VetoableChangeSupport(this);
//Phng thc ly v giá tr ca thuc tính size
public int getSize() { return size; }
//Phng thc dùng thay i giá tr ca thuc tính size
public void setSize(int newSize) {
int oldSize = size;
try { // Thông báo n tt c các i tng ã ng ký lng nghe
vetoAgent.fireVetoableChange("size", oldSize, newSize);
}
catch (PropertyVetoException ex) {
// Nu có mt listener nào ó phn i không cho phép thay i //giá tr ca thuc
tính size thì kt thúc phng thc
return;
}
//Nu tt c các listener u không phn i s thay i thì // tin hành gán giá tr mi
cho thuc tính size
size = newSize;
}
//Phng thc dùng ng ký i tng lng nghe
public void addSizeListener(VetoableChangeListener lst) {
vetoAgent.addVetoableChangeListener(lst);
}
//Phng thc dùng g bi tng lng nghe
public void removeSizeListener(VetoableChangeListener lst) {
vetoAgent.removeVetoableChangeListener(lst);
}
}
Ví d sau dùng test th BeanB va to
// TestBeanB.java
import java.beans.*;
public class TestBeanB {
public static void main(String[] args) {