RickyIT 2009-12-19
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组件的方法。
packagecom.skysoft.rbac.dao;
importorg.springframework.context.ApplicationContext;
importorg.springframework.web.context.support.WebApplicationContextUtils;
importjavax.faces.context.FacesContext;
importjavax.servlet.ServletContext;
importjavax.faces.el.ValueBinding;
importjavax.faces.FactoryFinder;
importjavax.faces.application.Application;
importjavax.faces.application.ApplicationFactory;
publicfinalclassSpringFacesUtil{
publicSpringFacesUtil(){
}
/**
*从Spring中查找bean.
*@parambeannameString
*@returnObject
*/
publicstaticObjectfindBean(Stringbeanname){
ServletContextcontext=(ServletContext)FacesContext.getCurrentInstance().
getExternalContext().getContext();
ApplicationContextappctx=WebApplicationContextUtils.
getRequiredWebApplicationContext(context);
returnappctx.getBean(beanname);
}
/**
*从JSF中查找bean.
*@parambeannameString
*@returnObject
*/
publicstaticObjectlookupBean(Stringbeanname){
Objectobj=getValueBinding(getJsfEl(beanname)).getValue(FacesContext.
getCurrentInstance());
returnobj;
}
privatestaticValueBindinggetValueBinding(Stringel){
returngetApplication().createValueBinding(el);
}
privatestaticApplicationgetApplication(){
ApplicationFactoryappFactory=(ApplicationFactory)FactoryFinder.
getFactory(FactoryFinder.APPLICATION_FACTORY);
//FactoryFinder.FACES_CONTEXT_FACTORY
//FactoryFinder.RENDER_KIT_FACTORY
returnappFactory.getApplication();
}
privatestaticStringgetJsfEl(Stringvalue){
return"#{"+value+"}";
}
}
下面定义一个由JSF管理的bean:
packagecom.skysoft.rbac.dao;
importjavax.servlet.ServletContext;
importorg.springframework.context.ApplicationContext;
importorg.springframework.web.context.support.WebApplicationContextUtils;
importorg.skysoft.struts.jsf.util.FacesUtils;
publicclassServiceLocatorBean
implementsServiceLocator{
privatestaticfinalStringDAO_SERVICE_BEAN_name="userDAO";
//这个dao就是由Spring提供的管理bean,这个dao可以使用Hibernate实现.
privateUserDAOdao;
publicServiceLocatorBean(){
this.dao=(UserDAO)SpringFacesUtil.findBean(DAO_SERVICE_BEAN_NAME);
}
publicUserDAOgetDao(){
returndao;
}
}
下面是一个使用ServiceLocatorBean的类。
publicclassUserDAOImp
extendsHibernateDaoSupportimplementsUserDAO{
privateUserDAOdao;
privateListlist;
publicUserDAOImp(){}
publicListgetList(){
if(list==null){
list=dao.getList();
}
returnlist;
}
publicUserDAOgetDao(){
returndao;
}
publicvoidsetDao(UserDAOdao){
this.dao=dao;
}
}
下面是一个使用ServiceLocatorBean的类:
publicclassUserDAOImp
extendsHibernateDaoSupportimplementsUserDAO{
privateUserDAOdao;
privateListlist;
publicUserDAOImp(){}
publicListgetList(){
if(list==null){
list=dao.getList();
}
returnlist;
}
publicUserDAOgetDao(){
returndao;
}
publicvoidsetDao(UserDAOdao){
this.dao=dao;
}
}
在faces-config.xml中的配置:
<managed-bean>
<managed-bean-name>serviceLocatorBeanmanaged-bean-name>
<managed-bean-class>com.skysoft.rbac.dao.ServiceLocatorBeanmanaged-bean-class>
<managed-bean-scope>sessionmanaged-bean-scope>
managed-bean>
<managed-bean>
<managed-bean-name>Usermanaged-bean-name>
<managed-bean-class>com.skysoft.rbac.Usermanaged-bean-class>
<managed-bean-scope>requestmanaged-bean-scope>
<managed-property>
<property-name>serviceLocatorproperty-name>
<property-class>com.skysoft.rbac.dao.ServiceLocatorBeanproperty-class>
<value>#{serviceLocatorBean}value>
</managed-property>
</managed-bean>
在applicationContext.xml中的配置:
<beanid="userDAO"class="com.skysoft.rbac.dao.UserDAOImp">
<propertyname="sessionFactory">
<reflocal="sessionFactory"/>
</property>
</bean>
则将javaee.jar包再copy一份放在tomcat目录的common\lib下就不会了。关于用到的javaee.jar、jsf-api.jar、jsf-impl.jar、jstl-1.2.jar