2025-05-23

在以往的應用開發過程中,後端的業務組件(Action/Service/Dao),可以被設置為幾種作用域:request、session、application。我們不可能把與每次請求關系很強的一些信息(例如某個列表頁面要列出來的數據集合)簡單的放到session裡面去,這就導致瞭每次請求之間的大部分數據是不可能共享的。使用JSF,我們實現瞭一種叫做view的作用域,在不同的請求之間共享信息。



新版的spring中提出瞭一個conversation作用於,也是介於request和session之間的一個作用於,和seam中的conversation應該差不多。


 



view作用域是生命周期介於request和session之間的一個作用范圍。當一個Spring Bean(一般來說是Action層面的Bean)被標註作用域為view的時候,Spring會在需要用到這個Bean的時候創建之,然後,在當前頁面沒有發生整頁的reload、跳轉的情況下,這個bean一直存在。所謂整頁reload、跳轉說的就是我們普通的表單提交,URL GET請求。發生除此之外的其他請求(目前能想到的其實也就是一種:Ajax請求)的時候,前面創建出來的bean對象一直存在。看一個具體的例子,首先是頁面:


 



 <!– some.xhtml –>
 <html xmlns=”http://www.w3.org/1999/xhtml”
     xmlns:h=”http://java.sun.com/jsf/html”
     xmlns:a4j=”http://richfaces.org/a4j”>
     <h:form>
         用戶名:<h:outputText value=”#{someAction.user.username}”/><br/>
         新密碼:<h:inputSecret value=”#{someAction.password}”/><br/>
         <a4j:commandButton value=”修改密碼” action=”#{someAction.save}”/>
     </h:form>
 </html>


 



這個頁面實現修改一個用戶的密碼,當我們請求這個頁面的時候,JSF發現你要使用someAction這個對象,所以他會告訴Spring去創建這樣一個對象。並且做瞭一些初始化工作:


 


 


package test;
//imports. 
@Component        //配置為Spring Bean
@Scope(“view”)    //作用域為view
public class SomeAction{
    private User user;
    private String password;
    private UserManager userManager;    //自動註入的userManager 


    @PostConstruct
    public void init(){
        this.user = this.userManager.get(1);//查找id為1的用戶
    } 


    public void save(){
        if(StringUtils.isNotBlank(this.password)){
            this.user.setPassword(this.password);
            this.userManager.saveOrUpdate(this.user);
        }
        else
            throw new ValidatorException(“Wrong password!”);
    } 
    //getters and setters


 


 


Spring創建SomeAction類的一個對象後,會馬上調用init方法,初始化其user屬性。然後頁面展現出來瞭,頁面上你看到瞭用戶名,和密碼輸入框。然後我們填寫一個新的密碼,點擊按鈕提交表單。註意我們的按鈕用的是<a4j:commandButton/>,這個按鈕會采用AJAX的方式提交當前表單。後端JSF接收到這個請求的時候,會調用頁面加載的時候創建的那個SomeAction對象的save方法。於是user對象也正是頁面加載的時候查詢出來的那個user對象。


 



看到瞭吧,在表單以ajax方式提交的時候,由於SomeAction是view作用域的,所以someAction對象依然是頁面加載時候創建的的那個對象,其中的User屬性也不需要你再次根據請求中的userId去查詢數據庫。


以此類推,我們在一個列表頁面加載的時候,使用一個view作用域的bean作為其action對象,於是加載完成後,要對列表中的某些行執行操作的時候,你都不需要再次去查詢,因為整個對象集合都依然存在!



本質上講,view作用域中的數據時被放在瞭session中。但是JSF實現瞭對於這寫內容的管理方式,不需要使用人員關心。


 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *