JSF和Spring集成原理是獲得彼此的上下文引用,以此進一步獲得各自管理的bean,這是可能的,因為兩者是web應用框架都遵循servlet規范,為二者整合提供了可能和基礎.
           
          在Spring中ApplicationContext是相當重要的類,對于web應用,它還包裝了javax.servlet.ServletContext,為web應用提供了所有可以利用的數據,包括可管理bean,Faces中通過FacesContext類可以獲得所有可以利用的資源,同樣包括JSF的可管理支持bean,它們都圍繞著ServletContext提供了自己的門面,通過各自的門面在Servlet容器的世界里彼此相通.
          本文介紹兩種方式,實現二者集成:
          1.         通過寫自己的類來完成二者的連通,實際上只是獲得彼此世界里存活的bean,對于JSF中事件處理可能需要更進一步的構思和編碼,為了這點,第二個方法介紹了一種框架.
          2.         使用框架完成二者集成.
           
          一  自己動手,下面的代碼以示例為主,其它涉及的類和接口略去.
          這個工具類提供在JSF世界里查找Spring管理的bean.也實現在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 + "}";
            }
          }
          下面定義一個由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";
            //這個dao就是由Spring提供的管理bean,這個dao可以使用Hibernate實現.
            private UserDAO dao;
           
            public ServiceLocatorBean() {
              this.dao = (UserDAO)SpringFacesUtil.findBean(DAO_SERVICE_BEAN_NAME);
            }
           
            public UserDAO getDao() {
              return dao;
            }
          }
          下面是一個使用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</managed-bean-name>
                        <managed-bean-class>com.skysoft.rbac.dao.ServiceLocatorBean</managed-bean-class>
                        <managed-bean-scope>session</managed-bean-scope>
                 </managed-bean>
                 <managed-bean>
                        <managed-bean-name>User</managed-bean-name>
                        <managed-bean-class>com.skysoft.rbac.User</managed-bean-class>
                        <managed-bean-scope>request</managed-bean-scope>
                        <managed-property>
                               <property-name>serviceLocator</property-name>
                               <property-class>com.skysoft.rbac.dao.ServiceLocatorBean</property-class>
                               <value>#{serviceLocatorBean}</value>
                        </managed-property>
                 </managed-bean>
          在applicationContext.xml中的配置:
                 <bean id="userDAO" class="com.skysoft.rbac.dao.UserDAOImp">
                        <property name="sessionFactory">
                               <ref local="sessionFactory" />
                        </property>
                 </bean>
          二 使用框架
          1 介紹
          這個框架是Spring相關項目,提供一個包de.mindmatters.faces.spring,這個包包含JSF和Spring框架綜合集成的粘合代碼,這些代碼以獨立于一個實現的方式完成,這樣它能和任何JSF實現一起使用.
          本包的提供的代碼主要目的是盡可能透明的集成兩個框架,主要特征:
          l         JSF/JSP開發者應該能訪問Spring管理的Beans,就好象它們是由JSF管理的.
          l         JSF可管理beans應能集成入Spring.
          l         RequestHandledEvent事件也應該能被發布到Spring.
          2  JSF配置集成
          本包構造了一個基于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就是全特征的,即自動擁有如下功能:
          l         JSF可管理beans實現了Spring的*Aware interfaces:
          ApplicationContextAware
          BeanFactoryAware
          BeanNameAware
          ResourceLoaderAware
          ServletContextAware
          l         JSF可管理beans實現Spring的lifecycle interfaces:
          InitializingBean
          DisposableBean
          l         實現Spring的FactoryBean interface
          l         實現Spring的ApplicationListener interface
          l         發布ApplicationEvent事件.
          l         從資源中讀取消息.
          等等,更多可看Spring.
          3 訪問方式
          1) 從JSF中程序化的訪問Spring管理的beans.
          因為在FacesWebApplicationContext和ApplicationContext之間有層次關系,所以你的JSF可管理支持beans能容易的實現ApplicationContextAware接口,并能通過getBean方法訪問它而不管它是否定義在FacesWebApplicationContext中還是定義在父ApplicationContext類對象中.
          2) 通過JSF EL從JSF中訪問Spring管理的beans.
          能夠使用JSF EL訪問beans無論你引用的bean由JSF管理還是由Spring管理.兩個bean上下文在存取時間合并.
          a) 直接訪問:
          如果一個帶有請求名字的bean只存在于Spring上下文內的話,這個bean被使用,bean的singleton屬性設置被完全保持.
          b) 區域化訪問(scoped access):
          如果你要從JSF定義bean的作用域的能力上得益還想讓那個bean由Spring管理,那么就要在兩個上下文中定義,只是對于JSF上下文中的定義的類類型要使用de.mindmatters.faces.spring.SpringBeanFactory類,你還應該設置那個bean的singleton屬性到false,因這能覆蓋你的作用域設置.在你使用JSF EL訪問bean時,你總能獲得一個遵從你在JSF上下文中定義的作用域設置的由Spring管理的bean的實例.
           
          三 用法
          通常,就象設置任何其它JSF web應用一樣設置你的web應用,下面的樣例配置展示怎樣使能上面提到的特征。
          在web.xml配置中必須加入下列配置條目,同時注意把該庫的jsf-spring.jar放在適當的位置.
          <web-app>
              .........
              <!--
                  過濾器用于向Spring發布RequestHandledEvent,它應該影射到和FacesServlet url相同的模式.
              -->   
              <filter>
                  <filter-name>RequestHandled</filter-name>
                  <filter-class>de.mindmatters.faces.spring.support.RequestHandledFilter</filter-class>
              </filter>
                
              <filter-mapping>
                  <filter-name>RequestHandled</filter-name>
                  <url-pattern>*.faces</url-pattern>
              </filter-mapping>
           
              <!--
              這個偵聽器用于裝入Spring beans的父應用上下文.
              -->
              <listener>
                  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
              </listener>
              .........
          </web-app>
          下面的一些說明,都可以通過下載這個Spring相關項目得到,列在這里只為演示上面的說明的功能.
          WEB-INF/faces-config.xml
          <!-- 一個純JSF管理的bean -->
          <managed-bean>
              <managed-bean-name>jsfBean</managed-bean-name>
              <managed-bean-class>example.NameBean</managed-bean-class>
              <managed-bean-scope>session</managed-bean-scope>
              <managed-property>
                  <property-name>name</property-name>
              </managed-property>
          </managed-bean>
          <!--一個SpringBeanScope用來定義Spring可管理bean的作用域.-->
                 <managed-bean>
                        <managed-bean-name>scopedAccessSpringBean</managed-bean-name>
                 <managed-bean-class>de.mindmatters.faces.spring.SpringBeanScope</managed-bean-class>
                        <managed-bean-scope>session</managed-bean-scope>
                 </managed-bean>
          <!-- 這是一個純JSF可管理bean,它持有一個到Spring可管理bean的一個引用. -->
          <managed-bean>
              <managed-bean-name>referencingBean</managed-bean-name>
              <managed-bean-class>example.ReferencingBean</managed-bean-class>
              <managed-bean-scope>session</managed-bean-scope>
              <managed-property>
                  <property-name>referencedBean</property-name>
                  <value>#{managedPropertyAccessSpringBean}</value>
              </managed-property>
          </managed-bean>
          WEB-INF/applicationContext.xml (partial)
          <!-- 一個純Spring的可管理bean -->
          <bean id="directAccessSpringBean" class="example.NameBean"/>
          <!-- 一個向JSF作用域提供的可管理bean.  -->
          <bean id="scopedAccessSpringBean" class="example.NameBean" singleton="false"/>
          <!-- 一個純Spring的可管理bean,它由一個JSF可管理bean引用.(當然了,它也能被直接訪問啦.) -->
          <bean id="managedPropertyAccessSpringBean" class="example.NameBean" singleton="false"/>
          參考:
          http://jsf-spring.sourceforge.net/   JSF-Spring,Spring相關項目官方站點,提供本文介紹的框架下載以及實例下載.
          javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html">http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html 一篇關于JSF和Spring的文章.
          bean的singleton屬性設置被完全保持.

          b) 區域化訪問(scoped access):
          如果你要從JSF定義bean的作用域的能力上得益還想讓那個bean由Spring管理,那么就要在兩個上下文中定義,只是對于JSF上下文中的定義的類類型要使用de.mindmatters.faces.spring.SpringBeanFactory類,你還應該設置那個bean的singleton屬性到false,因這能覆蓋你的作用域設置.在你使用JSF EL訪問bean時,你總能獲得一個遵從你在JSF上下文中定義的作用域設置的由Spring管理的bean的實例.
           
          三 用法
          通常,就象設置任何其它JSF web應用一樣設置你的web應用,下面的樣例配置展示怎樣使能上面提到的特征。
          在web.xml配置中必須加入下列配置條目,同時注意把該庫的jsf-spring.jar放在適當的位置.
          <web-app>
              .........
              <!--
                  過濾器用于向Spring發布RequestHandledEvent,它應該影射到和FacesServlet url相同的模式.
              -->   
              <filter>
                  <filter-name>RequestHandled</filter-name>
                  <filter-class>de.mindmatters.faces.spring.support.RequestHandledFilter</filter-class>
              </filter>
                
              <filter-mapping>
                  <filter-name>RequestHandled</filter-name>
                  <url-pattern>*.faces</url-pattern>
              </filter-mapping>
           
              <!--
              這個偵聽器用于裝入Spring beans的父應用上下文.
              -->
              <listener>
                  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
              </listener>
              .........
          </web-app>
          下面的一些說明,都可以通過下載這個Spring相關項目得到,列在這里只為演示上面的說明的功能.
          WEB-INF/faces-config.xml
          <!-- 一個純JSF管理的bean -->
          <managed-bean>
              <managed-bean-name>jsfBean</managed-bean-name>
              <managed-bean-class>example.NameBean</managed-bean-class>
              <managed-bean-scope>session</managed-bean-scope>
              <managed-property>
                  <property-name>name</property-name>
              </managed-property>
          </managed-bean>
          <!--一個SpringBeanScope用來定義Spring可管理bean的作用域.-->
                 <managed-bean>
                        <managed-bean-name>scopedAccessSpringBean</managed-bean-name>
                 <managed-bean-class>de.mindmatters.faces.spring.SpringBeanScope</managed-bean-class>
                        <managed-bean-scope>session</managed-bean-scope>
                 </managed-bean>
          <!-- 這是一個純JSF可管理bean,它持有一個到Spring可管理bean的一個引用. -->
          <managed-bean>
              <managed-bean-name>referencingBean</managed-bean-name>
              <managed-bean-class>example.ReferencingBean</managed-bean-class>
              <managed-bean-scope>session</managed-bean-scope>
              <managed-property>
                  <property-name>referencedBean</property-name>
                  <value>#{managedPropertyAccessSpringBean}</value>
              </managed-property>
          </managed-bean>
          WEB-INF/applicationContext.xml (partial)
          <!-- 一個純Spring的可管理bean -->
          <bean id="directAccessSpringBean" class="example.NameBean"/>
          <!-- 一個向JSF作用域提供的可管理bean.  -->
          <bean id="scopedAccessSpringBean" class="example.NameBean" singleton="false"/>
          <!-- 一個純Spring的可管理bean,它由一個JSF可管理bean引用.(當然了,它也能被直接訪問啦.) -->
          <bean id="managedPropertyAccessSpringBean" class="example.NameBean" singleton="false"/>
          參考:
          http://jsf-spring.sourceforge.net/   JSF-Spring,Spring相關項目官方站點,提供本文介紹的框架下載以及實例下載.
          http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html 一篇關于JSF和Spring的文章.

          posted on 2008-01-03 16:31 LifeNote 閱讀(1300) 評論(0)  編輯  收藏 所屬分類: JavaSpring
           
          主站蜘蛛池模板: 梨树县| 巨野县| 织金县| 囊谦县| 天门市| 永年县| 酒泉市| 新营市| 江达县| 南江县| 武隆县| 伊通| 铜梁县| 杨浦区| 呼伦贝尔市| 伊金霍洛旗| 莲花县| 贡山| 横峰县| 土默特左旗| 迭部县| 莱阳市| 锡林郭勒盟| 南宁市| 芜湖县| 井研县| 开原市| 莒南县| 肃宁县| 林甸县| 龙州县| 师宗县| 贺兰县| 左贡县| 库尔勒市| 大同县| 黄龙县| 布拖县| 南昌市| 屯留县| 中方县|