JSF擁有一個(gè)簡(jiǎn)單的依賴(lài)注入
在JSF MBF的管理之下的POJO
Managed-Bean類(lèi)型 | 昵稱(chēng) | 典型的有效域 |
---|---|---|
Model Managed-Bean | model-bean | session |
描述: 這種類(lèi)型的Managed-Bean充當(dāng)MVC設(shè)計(jì)模式中的"模型(Model)"部分。當(dāng)你看到"模型"一詞————可以把它想象為"數(shù)據(jù)"。一個(gè) JSF的model-bean應(yīng)該是一個(gè)遵循JavaBean規(guī)范的,以getter/setter方式封裝了各種屬性的普通JAVA對(duì)象。model- bean最常見(jiàn)的使用場(chǎng)景是作為一個(gè)數(shù)據(jù)庫(kù)實(shí)體,或簡(jiǎn)單地代表了數(shù)據(jù)庫(kù)查詢(xún)結(jié)果集中的一系列行數(shù)據(jù)。 | ||
Backing Managed-Bean | backing-bean | request |
描述: 這種類(lèi)型的Managed-Bean充當(dāng)MVC設(shè)計(jì)模式中的"視圖(View)"部分。backing-bean的目的是支持UI邏輯,(通常)與一個(gè) JSF視圖或Facelet聚合中的JSF表單保持一一對(duì)應(yīng)的關(guān)系。雖然它通常具有一些遵循JavaBean風(fēng)格并關(guān)聯(lián)了getter/setter的屬 性,但這些屬性是對(duì)應(yīng)"視圖"中的值,而不對(duì)應(yīng)底層的應(yīng)用數(shù)據(jù)模型。JSF的backing-bean可以具有JSF的actionListener和 valueChangeListener方法。 | ||
Controller Managed-Bean | controller-bean | request |
描述: 這種類(lèi)型的Managed-Bean充當(dāng)MVC設(shè)計(jì)模式中的"控制器(Controller)"部分。controller bean的目的是執(zhí)行某些業(yè)務(wù)邏輯并返回一個(gè)導(dǎo)航結(jié)果給JSF的導(dǎo)航處理器。JSF controller-bean通常具有JSF的action方法(而不是actionListener方法) | ||
Support Managed-Bean | support-bean | session / application |
描述: 這種類(lèi)型的bean為MVC設(shè)計(jì)模式中的"視圖(View)"部分中的一個(gè)或多個(gè)視圖提供"支持"。典型的應(yīng)用場(chǎng)景是提供一個(gè) ArrayList<SelectItem>給JSF的h:selectOneMenu下拉列表,而且這個(gè)下拉列表將在多個(gè)JSF視圖中出 現(xiàn)。如果這個(gè)下拉列表的數(shù)據(jù)是用戶(hù)特定的,那么這個(gè)bean就應(yīng)該放在session范圍中。但是,如果數(shù)據(jù)是提供給所有用戶(hù)的(例如一個(gè)選擇省份的下拉 列表),那么這個(gè)bean就應(yīng)該放在application范圍中。 | ||
Utility Managed-Bean | utility-bean | application |
描述: 這種bean為一個(gè)或多個(gè)JSF視圖提供"工具"。例如一個(gè)能在多個(gè)Web應(yīng)用中復(fù)用的FileUpload bean。 |
進(jìn)行這種區(qū)分的一個(gè)主要好處是松耦合。你會(huì)問(wèn):這是蝦米?那么,讓我們先看一個(gè)緊耦合的例子,在這里MVC的概念被拼湊(或者說(shuō)混淆)在單一的Managed-Bean中:
public class ModelAndBackingAndControllerBean {
private String fullName; // model-bean property
private boolean privacyRendered; // backing-bean property
// model-bean getter
public String getFullName() {
return fullName;
}
// model-bean setter
public void setFullName(String fullName) {
this.fullName = fullName;
}
// backing-bean getter
public boolean isPrivacyRendered() {
return privacyRendered;
}
// backing-bean setter
public void setPrivacyRendered(boolean privacyRendered) {
this.privacyRendered = privacyRendered;
}
// backing-bean actionListener for UI support logic
public void togglePrivacySection(ActionEvent actionEvent) {
privacyRendered = !privacyRendered;
}
// controller-bean business logic
public String submit() {
System.out.println("fullName=" + fullName);
return "success";
}
}
這種寫(xiě)法的問(wèn)題是由于它充當(dāng)model-bean,整個(gè)bean必須放在session范圍。并且,當(dāng)你想使用偽裝的模型數(shù)據(jù)(mock model data)進(jìn)行單元測(cè)試,你會(huì)發(fā)現(xiàn)根本行不通。因此為了修正這些問(wèn)題,并實(shí)現(xiàn)松耦合,我們應(yīng)該使用三個(gè)獨(dú)立的Java類(lèi):
public class ModelBean {
private String fullName;
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getFullName() {
return fullName;
}
}
public class BackingBean {
private boolean privacyRendered;
public void setPrivacyRendered(boolean privacyRendered) {
this.privacyRendered = privacyRendered;
}
public boolean isPrivacyRendered() {
return privacyRendered;
}
public void togglePrivacySection(ActionEvent actionEvent) {
privacyRendered = !privacyRendered;
}
}
public class ControllerBean {
private ModelBean modelBean;
public ModelBean getModelBean() {
return modelBean;
}
public void setModelBean(ModelBean modelBean) {
// Dependency injected from the JSF managed-bean facility
this.modelBean = modelBean;
}
public String submit() {
System.out.println("fullName=" + getModelBean().getFullName());
return "success";
}
}
現(xiàn)在這些bean實(shí)例將屬于不同的類(lèi),可以分別保持在合適的有效域中。model-bean可以放在session范圍,backing-bean和controller-bean可以放在request范圍,因而節(jié)省了服務(wù)器的內(nèi)存資源。
最后,我們可以使用JSF MBF提供的依賴(lài)注入特性來(lái)把model-bean注入到controller-bean中。下面是WEB-INF/faces-config.xml配置文件示例,其中#{modelBean} EL表達(dá)式即為注入的配置:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
version="1.2">
<managed-bean>
<managed-bean-name>modelBean</managed-bean-name>
<managed-bean-class>myproject.ModelBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>backingBean</managed-bean-name>
<managed-bean-class>myproject.BackingBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>controllerBean</managed-bean-name>
<managed-bean-class>myproject.ControllerBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>modelBean</property-name>
<value>#{modelBean}</value>
</managed-property>
</managed-bean>
</faces-config>