Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 281|回复: 0

[jsf学习]JSF和Spring集成

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-10 03:54:11 | 显示全部楼层 |阅读模式
    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相关项目官方站点,提供本文介绍的框架下载以及实例下载.
      
      
      http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html 一篇关于JSF和Spring的文章.
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-5-8 05:04 , Processed in 0.449622 second(s), 48 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表