转载于:http://210.34.136.253:8488/WebProg/webchpt28.htm
一个多层体系结构应该作为Web应用程序的高级体系结构。JSF很适合MVC设计模式,能够被用于实现表示层。Spring框架能被用于业务逻辑层去管理业务对象,提供声明性事务管理和资源管理。Spring与Hibernate结合的很好。Hibernate是一个强有力的O/R映射框架,能够提供数据层的服务。本章分别介绍介绍JSF与Spring框架的整合和Spring与Hibernate框架的整合,最后通过实例详细介绍多层架构的应用
1. 轻量级多层JavaEE架构分析
JSF、 Spring与Hibernate有各自的优点与不足,将这三个框架有效整合在一起,能够有效搭建三层或多层系统,保证了清晰的职责划分以及可维护性和可扩展性。三层或多层系统已经被证明比没有业务逻辑层的客户-服务器系统具有更多的可升级性和柔韧性。通常多层架构系统划分为:客户端、表现层、业务逻辑层和数据持久层。
客户端是数据模型被消费和呈现的地方。由于目前流行的是B/S架构的系统,对于一个Web应用程序,客户层通常是Web浏览器。基于浏览器的瘦客户不包含表现逻辑,它依赖于表现层展现。
表现层使用业务逻辑层为用户服务,它知道怎样去处理一个客户请求,怎样去和业务逻辑层结合以及怎样去选择下一个数据并试图去显示。
业务逻辑层包含一个应用程序的业务对象和业务服务。它从表示层接受请求,基于请求处理业务逻辑,作为访问数据持久层资源的中介。业务逻辑层组件使用许多系统级别的服务,例如,安全管理、事务管理和资源管理。
数据持久层是业务逻辑层和数据库之间的桥梁。它封装了与数据库访问相结合的逻辑。图1-1 多层软件架构
表现层的功能是收集用户的输入、展示数据、控制页面导航并将用户的输入传递给业务逻辑层,表示层同时需要验证用户的输入以及维护应用的 session状态。JSF是Web应用的服务器端用户组件框架,它包含以下API:表示UI组件、管理它们的状态、处理事件、服务器端验证、数据转换、定义页面导航、支持国际化,并为这些特性提供扩展能力。它同时包括两个JSP的tag库以在JSP页面中表示UI组件,以及将组件wire为服务器端对象。JSF非常适合于基于MVC的表示层架构,它为行为和表示之间提供了清晰的分离。
业务逻辑层提供了应用客户所需要的业务服务,它包含有业务数据和业务逻辑。通常对应用请求的大部分业务集中在这一层处理。它从表示层接受请求,基于请求处理业务逻辑,作为访问数据资源层中介。Spring是基于IoC概念的框架,在事务管理和依赖注射方面有着独到之处。Spring能有效地组织中间层对象,利用AOP(Aspect-Oriented Programming)实现垂直处理,避免一个实体功能的分解,促进面向对象设计的实现。
选用Hibernate作为数据持久层的实现技术。Hibernate是一个开源O/R映射框架,对JDBC进行了轻量级的对象封装。它提供数据恢复和更新的工具、事务管理、数据连接池,声明实体关系的管理等。支持所有主流的SQL数据库管理系统。Hibernate的HQL(Hibernate Query Language)查询数据语言是SQL面向对象的最小的扩展来设计的,在对象和关系领域间提供了一个交互的桥。2.JSF与Spring的整合
JSF与Spring整合的重点问题在于:怎样让JSF管理的页面后台JavaBean访问到由Spring管理的业务逻辑层的JavaBean,而表现层的页面及页面后台的控制逻辑仍由JSF管理。如图1-2所示。
图1-2 JSF与Spring的整合
这里需要让JSF和Spring获得彼此的应用程序上下文配置文件(ApplicationContext),以此进一步获得各自管理的Bean。
在上一章介绍了使用Spring的BeanFactory实例化对象。BeanFactory提供的高级配置机制,可以管理任何性质的对象。而 ApplicationContext是Spring中相当重要的类,它是BeanFactory的扩展,功能得到了进一步增强,比如更易与Spring AOP集成、消息资源处理(国际化处理)、事件传递及各种不同应用层的context实现(如针对Web应用的WebApplicationContext,它继承了ApplicationContext)。
简而言之,BeanFactory提供了配制框架及基本功能,而ApplicationContext则增加了更多支持企业核心内容的功能。 ApplicationContext完全由BeanFactory扩展而来,因而BeanFactory所具备的能力和行为也适用于 ApplicationContext。对于Web应用,初始化WebApplicationContext在web.xml文档中定义。具体定义如下:
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/conf/spring/*.xml</param-value>
</context-param>
<context-param>
<param-name>javax.faces.CONFIG_FILES</param-name>
<param-value>/WEB-INF/conf/jsf/faces-context.xml</param-value>
</context-param>
在web.xml 文件中声明一个ContextLoaderListener监听器,用来在Web应用启动的时候来初始化WebApplicationContext。并且在同一文件里增加一个 contextConfigLocation参数,它的值决定了哪些 Spring XML配置文件将要被加载。上例中,说明在Web项目根目录下的/WEB-INF/conf/spring/目录下的所有扩展为xml的文件都需要加载。javax.faces.CONFIG_FILES的值指明需要加载的JSF配置文件。
另外,与JSF进行集成的关键类是DelegatingVariableResolver。为了在JSF应用程序中配置这个解析器,需要编辑JSF的配置文件faces-context.xml(任一个JSF配置文件都可)。在<faces-config/>元素里面增加一个<application/>节点和一个<variable-resolver/>节点。其中variable- resolver变量解析器的值将引用Spring的DelegatingVariableResolver。示例如下:<faces-config>
<application>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application>
</faces-config>
一旦页面对JavaBean有使用请求,DelegatingVariableResolver类将首先在JSF实现的默认的解析器中查询,其后在Spring的WebApplicationContext中去查找。这样,JSF要使用Spring管理的Bean就很容易,可以通过配置文件将Bean依赖注入到JSF管理的Bean中。这只需要在faces-context.xml文件内定义。例如在 UserBackingBean这个JSF管理的后台JavaBean中使用业务层的名为userManagerService的Bean。修改JSF的配置文件faces-context.xml增加如下内容:
<managed-bean>
<managed-bean-name>UserBB</managed-bean-name>
<managed-bean-class>
org.studadmin.web.UserBackingBean
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name> userService</property-name>
<value>#{UserManagerService}</value>
</managed-property>
</managed-bean>
<managed-bean-name>节点指明在页面使用后台Bean的名称。这里当页面使用UserBackingBean时,不用给出类所在路径,直接使用UserBB名称就行。<managed-property>节点说明在UserBackingBean类中使用了userService属性,这个属性值来源于UserManagerService,即Spring所管理的业务类。这样,当页面使用到后台 UserBackingBean类时,DelegatingVariableResolver则根据配置寻找到由Spring管理的 UserManagerService类。
至此,JSF与Spring的集成就完成了。如果要更全面的集成,可以查看JSF-Spring这个项目,专用于整合JSF与Spring。