JSF和Spring的集成
JSF和Spring集成的資料比較少,原理是獲得彼此的上下文引用,以此進(jìn)一步獲得各自管理的bean,這是可能的,因?yàn)閮烧呤莣eb應(yīng)用框架都遵循servlet規(guī)范,為二者整合提供了可能和基礎(chǔ).
 
在 Spring中ApplicationContext是相當(dāng)重要的類,對于web應(yīng)用,它還包裝了 javax.servlet.ServletContext,為web應(yīng)用提供了所有可以利用的數(shù)據(jù),包括可管理bean,Faces中通過 FacesContext類可以獲得所有可以利用的資源,同樣包括JSF的可管理支持bean,它們都圍繞著ServletContext提供了自己的門面,通過各自的門面在Servlet容器的世界里彼此相通.
本文介紹兩種方式,實(shí)現(xiàn)二者集成:
1. 通過寫自己的類來完成二者的連通,實(shí)際上只是獲得彼此世界里存活的bean,對于JSF中事件處理可能需要更進(jìn)一步的構(gòu)思和編碼,為了這點(diǎn),第二個(gè)方法介紹了一種框架.
2. 使用框架完成二者集成.
 
一  自己動(dòng)手,下面的代碼以示例為主,其它涉及的類和接口略去.
這個(gè)工具類提供在JSF世界里查找Spring管理的bean.也實(shí)現(xiàn)在Spring中查找JSF組件的方法.
- package com.skysoft.rbac.dao;
 - import org.springframework.context.ApplicationContext;
 - import org.springframework.web.context.support.WebApplicationContextUtils;
 - import javax.faces.context.FacesContext;
 - import javax.servlet.ServletContext;
 - import javax.faces.el.ValueBinding;
 - import javax.faces.FactoryFinder;
 - import javax.faces.application.Application;
 - import javax.faces.application.ApplicationFactory;
 - public final class SpringFacesUtil {
 - public SpringFacesUtil() {
 - }
 - /**
 - * 從Spring中查找bean.
 - * @param beanname String
 - * @return Object
 - */
 - public static Object findBean(String beanname) {
 - ServletContext context = (ServletContext) FacesContext.getCurrentInstance().
 - getExternalContext().getContext();
 - ApplicationContext appctx = WebApplicationContextUtils.
 - getRequiredWebApplicationContext(context);
 - return appctx.getBean(beanname);
 - }
 - /**
 - * 從JSF中查找bean.
 - * @param beanname String
 - * @return Object
 - */
 - public static Object lookupBean(String beanname) {
 - Object obj = getValueBinding(getJsfEl(beanname)).getValue(FacesContext.
 - getCurrentInstance());
 - return obj;
 - }
 - private static ValueBinding getValueBinding(String el) {
 - return getApplication().createValueBinding(el);
 - }
 - private static Application getApplication() {
 - ApplicationFactory appFactory = (ApplicationFactory) FactoryFinder.
 - getFactory(FactoryFinder.APPLICATION_FACTORY);
 - //FactoryFinder.FACES_CONTEXT_FACTORY
 - //FactoryFinder.RENDER_KIT_FACTORY
 - return appFactory.getApplication();
 - }
 - private static String getJsfEl(String value) {
 - return "#{" + value + "}";
 - }
 - }
 
下面定義一個(gè)由JSF管理的bean:
- package com.skysoft.rbac.dao;
 - import javax.servlet.ServletContext;
 - import org.springframework.context.ApplicationContext;
 - import org.springframework.web.context.support.WebApplicationContextUtils;
 - import org.skysoft.struts.jsf.util.FacesUtils;
 - public class ServiceLocatorBean
 - implements ServiceLocator {
 - private static final String DAO_SERVICE_BEAN_NAME = "userDAO";
 - //這個(gè)dao就是由Spring提供的管理bean,這個(gè)dao可以使用Hibernate實(shí)現(xiàn).
 - private UserDAO dao;
 - public ServiceLocatorBean() {
 - this.dao = (UserDAO)SpringFacesUtil.findBean(DAO_SERVICE_BEAN_NAME);
 - }
 - public UserDAO getDao() {
 - return dao;
 - }
 - }
 - 下面是一個(gè)使用ServiceLocatorBean的類.
 - public class UserDAOImp
 - extends HibernateDaoSupport implements UserDAO {
 - private UserDAO dao;
 - private List list;
 - public UserDAOImp() {}
 - public List getList() {
 - if (list == null) {
 - list = dao.getList();
 - }
 - return list;
 - }
 - public UserDAO getDao() {
 - return dao;
 - }
 - public void setDao(UserDAO dao) {
 - this.dao = dao;
 - }
 - }
 
下面是一個(gè)使用ServiceLocatorBean的類:
- public class UserDAOImp
 - extends HibernateDaoSupport implements UserDAO {
 - private UserDAO dao;
 - private List list;
 - public UserDAOImp() {}
 - public List getList() {
 - if (list == null) {
 - list = dao.getList();
 - }
 - return list;
 - }
 - public UserDAO getDao() {
 - return dao;
 - }
 - public void setDao(UserDAO dao) {
 - this.dao = dao;
 - }
 - }
 
在faces-config.xml中的配置:
- <managed-bean>
 - <managed-bean-name>serviceLocatorBean< SPAN>managed-bean-name>
 - <managed-bean-class>com.skysoft.rbac.dao.ServiceLocatorBean< SPAN>managed-bean-class>
 - <managed-bean-scope>session< SPAN>managed-bean-scope>
 - < SPAN>managed-bean>
 - <managed-bean>
 - <managed-bean-name>User< SPAN>managed-bean-name>
 - <managed-bean-class>com.skysoft.rbac.User< SPAN>managed-bean-class>
 - <managed-bean-scope>request< SPAN>managed-bean-scope>
 - <managed-property>
 - <property-name>serviceLocator< SPAN>property-name>
 - <property-class>com.skysoft.rbac.dao.ServiceLocatorBean< SPAN>property-class>
 - <value>#{serviceLocatorBean}< SPAN>value>
 - managed-property>
 - < SPAN>managed-bean>
 
在applicationContext.xml中的配置:
- <bean id="userDAO" class="com.skysoft.rbac.dao.UserDAOImp">
 - <property name="sessionFactory">
 - <ref local="sessionFactory" />
 - < SPAN>property>
 - < SPAN>bean>
 
二 使用框架
1.介紹
這個(gè)框架是Spring相關(guān)項(xiàng)目,提供一個(gè)包de.mindmatters.faces.spring,這個(gè)包包含JSF和Spring框架綜合集成的粘合代碼,這些代碼以獨(dú)立于一個(gè)實(shí)現(xiàn)的方式完成,這樣它能和任何JSF實(shí)現(xiàn)一起使用.
本包的提供的代碼主要目的是盡可能透明的集成兩個(gè)框架,主要特征:
◆JSF/JSP開發(fā)者應(yīng)該能訪問Spring管理的Beans,就好象它們是由JSF管理的.
◆JSF可管理beans應(yīng)能集成入Spring.
◆RequestHandledEvent事件也應(yīng)該能被發(fā)布到Spring.
2.JSF配置集成
本包構(gòu)造了一個(gè)基于faces配置文件(e.g. /WEB-INF/faces-config.xml)的WebApplicationContext類, 讓它成為遵循"spring-beans" DTD配置文件(e.g. defined in /WEB-INF/applicationContext.xml)來配置的ApplicationContext的孩子,這樣依從"faces- config" DTD的WebApplicationContext就是全特征的,即自動(dòng)擁有如下功能:
1)JSF可管理beans實(shí)現(xiàn)了Spring的*Aware interfaces:
◆ApplicationContextAware
◆BeanFactoryAware
◆BeanNameAware
◆ResourceLoaderAware
◆ServletContextAware
2)JSF可管理beans實(shí)現(xiàn)Spring的lifecycle interfaces:
InitializingBean
DisposableBean
◆實(shí)現(xiàn)Spring的FactoryBean interface
◆實(shí)現(xiàn)Spring的ApplicationListener interface
◆發(fā)布ApplicationEvent事件.
◆從資源中讀取消息.
等等,更多可看Spring.
3 訪問方式
1) 從JSF中程序化的訪問Spring管理的beans.
因?yàn)樵贔acesWebApplicationContext和ApplicationContext之間有層次關(guān)系,所以你的JSF可管理支持beans 能容易的實(shí)現(xiàn)ApplicationContextAware接口,并能通過getBean方法訪問它而不管它是否定義在 FacesWebApplicationContext中還是定義在父ApplicationContext類對象中.
2) 通過JSF EL從JSF中訪問Spring管理的beans.
能夠使用JSF EL訪問beans無論你引用的bean由JSF管理還是由Spring管理.兩個(gè)bean上下文在存取時(shí)間合并.
a) 直接訪問:
如果一個(gè)帶有請求名字的bean只存在于Spring上下文內(nèi)的話,這個(gè)bean被使用,bean的singleton屬性設(shè)置被完全保持.
b) 區(qū)域化訪問(scoped access):
如果你要從JSF定義bean的作用域的能力上得益還想讓那個(gè)bean由Spring管理,那么就要在兩個(gè)上下文中定義,只是對于JSF上下文中的定義的類類型要使用de.mindmatters.faces.spring.SpringBeanFactory類,你還應(yīng)該設(shè)置那個(gè)bean的 singleton屬性到false,因這能覆蓋你的作用域設(shè)置.在你使用JSF EL訪問bean時(shí),你總能獲得一個(gè)遵從你在JSF上下文中定義的作用域設(shè)置的由Spring管理的bean的實(shí)例.
 
三 用法
通常,就象設(shè)置任何其它JSF web應(yīng)用一樣設(shè)置你的web應(yīng)用,下面的樣例配置展示怎樣使能上面提到的特征。
在web.xml配置中必須加入下列配置條目,同時(shí)注意把該庫的jsf-spring.jar放在適當(dāng)?shù)奈恢?
- <web-app>
 - .........
 - <filter>
 - <filter-name>RequestHandled< SPAN>filter-name>
 - <filter-class>de.mindmatters.faces.spring.support.RequestHandledFilter< SPAN>filter-class>
 - < SPAN>filter>
 - <filter-mapping>
 - <filter-name>RequestHandled< SPAN>filter-name>
 - <url-pattern>*.faces< SPAN>url-pattern>
 - < SPAN>filter-mapping>
 - <listener>
 - <listener-class>org.springframework.web.context.ContextLoaderListener< SPAN>listener-class>
 - < SPAN>listener>
 - .........
 - < SPAN>web-app>
 
下面的一些說明,都可以通過下載這個(gè)Spring相關(guān)項(xiàng)目得到,列在這里只為演示上面的說明的功能.
WEB-INF/faces-config.xml 
- <managed-bean>
 - <managed-bean-name>jsfBean< SPAN>managed-bean-name>
 - <managed-bean-class>example.NameBean< SPAN>managed-bean-class>
 - <managed-bean-scope>session< SPAN>managed-bean-scope>
 - <managed-property>
 - <property-name>name< SPAN>property-name>
 - < SPAN>managed-property>
 - < SPAN>managed-bean>
 - <managed-bean>
 - <managed-bean-name>scopedAccessSpringBean< SPAN>managed-bean-name>
 - <managed-bean-class>de.mindmatters.faces.spring.SpringBeanScope< SPAN>managed-bean-class>
 - <managed-bean-scope>session< SPAN>managed-bean-scope>
 - < SPAN>managed-bean>
 - <managed-bean>
 - <managed-bean-name>referencingBean< SPAN>managed-bean-name>
 - <managed-bean-class>example.ReferencingBean< SPAN>managed-bean-class>
 - <managed-bean-scope>session< SPAN>managed-bean-scope>
 - <managed-property>
 - <property-name>referencedBean< SPAN>property-name>
 - <value>#{managedPropertyAccessSpringBean}< SPAN>value>
 - < SPAN>managed-property>
 - < SPAN>managed-bean>
 - WEB-INF/applicationContext.xml (partial)
 - <bean id="directAccessSpringBean" class="example.NameBean"/>
 - <bean id="scopedAccessSpringBean" class="example.NameBean" singleton="false"/>
 - <bean id="managedPropertyAccessSpringBean" class= "example.NameBean" singleton="false"/>
 
參考:
http://jsf-spring.sourceforge.net/   JSF-Spring,Spring相關(guān)項(xiàng)目官方站點(diǎn),提供本文介紹的框架下載以及實(shí)例下載.
http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html一篇關(guān)于JSF和Spring的文章.
【編輯推薦】















 
 
 
 
 
 
 