http://cagataycivici.wordpress.com/2010/02/17/port-jsf-2-0s-viewscope-to-spring-3-0/
译注:作者Cagatay Civici 是PrimeFaces 项目的创建者,也是MyFaces 的重要开发人员,他还是JSF2.0标准(JSR314) 的专家组成员之一,对JSF有在非常丰富的经验。
如果你正在使用JSF和Spring并且打算升级到JSF 2.0,或许你乐意去使用JSF2.0内建的viewscope。Spring不支持这个scope,因为它是特定于JSF2.0规范的。不过不用担心,使用Spring的自定义scope功能可以代理JSF2.0的viewscope,使其成为一个Spring bean的scope。
package org.primefaces.spring.scope;
import java.util.Map;
import javax.faces.context.FacesContext;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
blic class ViewScope implements Scope {
public Object get(String name, ObjectFactory objectFactory) {
Map<String,Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
if(viewMap.containsKey(name)) {
return viewMap.get(name);
} else {
Object object = objectFactory.getObject();
viewMap.put(name, object);
return object;
}
}
public Object remove(String name) {
return FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove(name);
}
public String getConversationId() {
return null;
}
public void registerDestructionCallback(String name, Runnable callback) {
//Not supported
}
public Object resolveContextualObject(String key) {
return null;
}
}
然后再Spring中注册这个自定义的scope:
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"> <property name="scopes"> <map> <entry key="view"> <bean class="org.primefaces.spring.scope.ViewScope"/> </entry> </map> </property> </bean>
现在就可以使用Spring的bean作为JSF的ViewScope的ManagedBean了。做一个例子测试一下,假设有一个简单的计数器页面,每点击一下计数器就随之增加。只要你待在这个页面,计数器的状态就被保持,直到你离开这个页面,计数器才被销毁。如果重新访问这个页面的话,计数器将重新开始。
package org.primefaces.spring.view;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("view")
public class CounterBean {
private int counter = 0;
public int getCounter() {
return counter;
}
public void setCounter(int counter) {
this.counter = counter;
}
public void increment() {
counter++;
}
}
<h:form> <h:outputText id="counter" value="#{counterBean.counter}" /> <p:commandButton value="Count" actionListener="#{counterBean.increment}" update="counter"/> </h:form>
让Spring提供JSF可以使用的ViewScope的backing beans,你可以享受到Spring容器提供的好处,同时也可以使用这个很方便的scope。对于JSF2.0中的FlashScope可以用同样的方式来实现。