JSF和Spring的集成

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;  
      }  
    } 
下面是一个使用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实现一起使用.
本包的提供的代码主要目的是尽可能透明的集成两个框架,主要特征:
◆JSF/JSP开发者应该能访问Spring管理的Beans,就好象它们是由JSF管理的.
◆JSF可管理beans应能集成入Spring.
◆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就是全特征的,即自动拥有如下功能:

1)JSF可管理beans实现了Spring的*Aware interfaces:
◆ApplicationContextAware
◆BeanFactoryAware
◆BeanNameAware
◆ResourceLoaderAware
◆ServletContextAware

2)JSF可管理beans实现Spring的lifecycle interfaces:
InitializingBean
DisposableBean
◆实现Spring的FactoryBean interface
◆实现Spring的ApplicationListener interface
◆发布ApplicationEvent事件.
◆从资源中读取消息.
等等,更多可看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> 
        .........  
             
        <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> 
       
         
        <listener> 
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
        </listener> 
        .........  
    </web-app> 
下面的一些说明,都可以通过下载这个Spring相关项目得到,列在这里只为演示上面的说明的功能.
WEB-INF/faces-config.xml

<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> 
 
       <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> 
 
<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) 
<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相关项目官方站点,提供本文介绍的框架下载以及实例下载.
http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html一篇关于JSF和Spring的文章.



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值