SpringSide科研管理系统
摘 要 提出了一种网络环境下,基于J2EE框架技术,借助分层思想,使用组件服务,利用SpringSide进行软件开发的方法。在基于网络的科研管理系统中,在表现层使用Struts,业务层使用Spring,持久层使用Hibernate,开发团队分工明确,极大地提高了开发的效率。
关键词 J2EE;SpringSide;科研管理;低耦合
1 引言
随着科技的日益发展,高校的科研活动和科研能力成为反映高校综合实力指标的比重不断加大。通过信息化手段对日常科研工作进行管理,整合科研工作流程,为决策层提供真实有效的依据,是提升科研管理水平的有效途径,也是当今高校科研管理的大势所趋。
通过科研管理信息化平台,可以实现科研工作的网络化管理,形成一个及时更新的科研数据中心和科研管理沟通平台,全面、实时、准确提供学校的有关科研信息,为学校领导有关科研决策提供辅助支持,为学校教师开展科研活动提供方便快捷的服务,为科研管理人员开展工作提供极大的便利。
首先,平台为所有从事科研活动的科研人员提供服务,为科研人员提供一个管理个人科研活动的网络空间,实现个人科研申报、成果登记、查询网络化,免除填写各种统计报表的麻烦,节省工作时间,提高工作效率。
其次,借助平台,科研管理人员可以方便地完成有关的科研管理任务,如项目申报组织、项目中检等工作,使各级领导可以及时了解和掌握本单位教师的科研情况。
第三,平台可以将各种数据进行汇总分析,形成直观的分析图标,进行横向和纵向比较,为领导提供学校各类科研信息,为科学决策提供支持。
第四,建立科学合理的考核体系,定义各种分类评价指标。以考核为推动力,拉动全体科研人员的积极性,使科研有序、高效,使平台成为日常工作中的科研平台。
最后,教师个人填报、科研管理人员审核后,全校的科研项目、科研论文、科研著作、学术活动、工作量统计和科研考核结果等数据信息即可在平台上显示,全体教职工均可以登录查询,通过不同的权限设置,对其中的数据进行修订和审核,保证数据的准确、真实性,并随时掌握学校最新的科研情况。
科研管理系统基于当前流行的J2EE框架技术SpringSide进行开发,包括Struts、Spring 、Hibernate等开发工具和环境。
2 J2EE架构的裁剪
J2EE架构由于其重量级的原因,在使用它开发时一般都要进行裁减。在当前的软件开发领域,人们一般将信息系统分为表现、持久、业务、领域模型等多个层次。其中,表现层的主要职责是为用户管理请求和响应,提供一个控制器代理调用业务逻辑和其它上层处理,处理从其它层抛出的异常,为显示提供一个模型以及执行用户接口(UI)验证等;持久层保存、更新、删除储存在数据库中的信息,通过持久层的逻辑隔离,应用程序变得易于修改而不会影响其它层的代码;业务层的职责是处理应用程序的业务逻辑和业务验证,管理事务,预留和其它层交互的接口,管理业务层对象之间的依赖,增加在表现层和持久层之间的灵活性,使它们互不直接通讯,从表现层中提供一个上下文给业务层获得业务服务(business services )以及管理从业务逻辑到持久层的实现;领域模型层由那些代表现实世界中的业务对象组成。
JSP+JavaBeans、struts等框架一般情况下是将表示层单独分离,由平面设计人员完成界面设计,开发人员用JavaBean或struts的action完成业务逻辑和持久化,以初步解决开发中的分工问题。但由于层与层之间紧密耦合,代码重用率较低,且各层分工也不太明确,不利于团队的明确分工,因此,这样的架构只适合于小型项目,应用到较大项目时,会产生问题。要对J2EE进行裁减,组成一个高效、松藕合的轻量级的架构,应基于两个原则:层次尽量分工明确,层次之间耦合度尽量低。在基于网络的科研管理系统中,在表现层使用Struts,业务层使用Spring,持久层使用Hibernate。
Struts是用于实现Web项目中UI层的开源产品,是MVC模式的经典实现案例。Struts将业务数据、页面显示、动作处理进行分离,有利各部分的文护;Struts采用Front Controller模式来实现动作处理,使所有动作请求经过一个统一的入口进行分发,方便在入口中加入一些全局控制代码的实现,如安全控制、日志管理、国际化编码等;通过Struts提供的ActionForm封装Web form中的元素,使重用Web表单成为可能;借助Struts Validator框架帮助完成Web层的验证工作,通常情况下不再为每个Web页面写验证代码,只需通过配置即可;用ActionForm类封装与用户互动的数据元素;用Action类实现逻辑(显示逻辑)、动作处理、链接转向,实现MVC中的Controller;借助Struts标签完成数据呈现,实现MVC中的View;ActionForm,Action,Validator的连接关系在struts-config.xml配置文件中定义;Struts运行在servlet容器中,加入容器配置文件Web.xml。
业务逻辑层Spring,通过控制反转、AOP应用、面向接口编程,降低业务组件之间的耦合度,增强系统扩展性。Spring 框架是一个分层架构,由七个定义良好的模块组成。其中最重要的模块是核心容器。核心容器定义了创建、配置和管理bean的方式,提供Spring框架的基本功能。核心容器的主要组件是BeanFactory,它是工厂模式的实现。BeanFactory使用控制反转(IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
以科研管理系统中的项目管理的实现原理为例来说明基于SpringSide的软件开发过程:作为领域对象的项目(Project)显示在Web页面(JSP、HTML等),通过struts对它进行的操作请求发送到相应的Action,在Action中通过Spring提供的服务定位器调用服务,Spring根据配置文件中的内容管理相应的业务逻辑Bean,业务逻辑调用Hibernate与数据库交互。
3 SpringSide架构技术
SpringSide以Spring Framework为核心,以Ruby On Rails的简约风格整合Java社区的众多开源项目,为开发Java企业应用提供了一个方便起点。它所整合的Full-Stack 的开源构件库,包括了WebService、JMS、工作流、安全、报表、规则引擎、搜索引擎、定时任务等企业应用特性,以构件式的开发架构,配合Ant脚本与SpringSide-IDE(Eclipse插件),作为一个一站式的快速Java开发框架。
SpringSide由Core、Examples、Tools三部分组成。以JDK5和Spring2.0作为架构的基础。Entity POJO类由Hibernate Annotation注释ORM关系,因为POJO属性与数据库默认一一映射,所需的注释很少。Manager类采用No Dao、No Interface的紧凑模式,继承HibernateEntityDAO基类,用泛型声明自己管理的Entity Class。Struts Action采用Pragmatic的新模式:DispatchAction 每个Controller 响应一组相关操作,LazyValidatorForm免去FormBean定义,同样采用了StrutsEntityAction基类。View层采用JSP2.0,并结合Prototype.js、Dojo 简化Javascript与Ajax 应用。
作为Java企业应用框架,SpringSide深度结合了JBPM 工作流引擎、JBossRules规则引擎、Birt报表引擎,Lucene/Compass搜索引擎,Acegi安全与权限管理,XFire Web服务与ActiveMQ JMS与ESB项目组成的SOA架构的构件式架构。
RoR是一种简约态度,使用最主流的Spring+ Struts+ Hibernate架构,配合JDK5就可以极少的代码行数完成CRUD式的模块。
4 基于SpringSide的开发过程
4.1 架构环境
架构包括的内容有J2EE容器(Servlet 2.4规范)、Struts包、Spring Framework包、Hibernate包、相应数据库的JDBC驱动器包。架构运行在J2EE容器上,可以在任何符合Servlet 2.4规范的J2EE容器上运行。
在J2EE容器的应用目录下生成应用名。根据J2EE规范,将自动创建以下几个子目录:Web-INFO,META-INF,JSP等。Web-INFO目录下有classes、lib等子目录。将所有相关的包放在Web-INFO/lib中。将Struts的ActionServlet加入到servlet配置中,将Spring加入到Web.xml配置。
4.2 开发过程
4.2.1 定义领域对象
分析科研管理系统中涉及的领域对象,编码或生成领域对象的源代码并将所有的领域对象打包成相应的java包,如com.srmis.bo。以科研项目管理为例,com.srmis.bo.Project.java表示一个领域对象,这是一个普通的JavaBean。
根据需要编写相应的hibernate映射文件Project.hbm. xml。在文件中定义对象属性和数据库表中的字段映射关系,并生成相应的数据库物理模型。将此XML文件存放在Project.java的相同目录下。
4.2.2 定义业务服务对象
为了充分体现分层间的松耦合关系,层间的协议采用接口定义。在用户层和业务逻辑层间定义业务服务接口(IprojectService),此接口定义要在Project对象上的操作。
public interface IprojectService {
public abstract Project saveNewProject(Project project)
throws ProjectException,ProjectMinimumAmount Exception;
public abstract List findProjectByUser( String user) throws ProjectException;
public abstract Project findProjectById(int id) throws ProjectException;
public abstract void setProjectDAO( IProjectDAO projectDAO);
}
代码中有一个为DAO对象准备的setter方法。DAO对象用来与持久层沟通。Spring把业务服务对象和DAO对象连在一起。
同时可以生成此接口的实现对象ProjectServiceImp.java。
将两个文件打包到:com.srmis.service。
4.2.3 实现DAO对象
在业务逻辑层和持久层间定义DAO接口(IprojectDao),此接口定义持久化的操作。
public interface IProjectDAO {
public abstract Project findProjectById(final int id);
public abstract List findProjectsPlaceByUser( final String placedBy);
public abstract Project saveProject(final Project project);
}
因Spring内建对Hibernate的支持,DAO接口的实现类com.srmis.dao.ProjectDAO将继承HibernateDaoSupport类,取得HibernateTemplate类的引用,HibernateTemplate是一个帮助类,能简化Hibernate Session的编码和HibernateExceptions的处理。
将两个文件打包到com.srmis.dao;
4.2.4 定义Spring配置文件
持久性对象HibernateSessionFactory和事务管理对象TransactionManager也要与业务层连在一起。只需在Spring配置文件中配置即可。
Spring提供一个HibernateTransactionManager,将从工厂绑定一个Hibernate Session到一个线程来支持事务。下列代码是HibernateSessionFactory和HibernateTransactionManager的Spring配置。
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate. LocalSessionFactoryBean">
<property name="mappingResources">
<list><value>com/srmis/bo/Project.hbm.xml</value></list>
</property>…
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory -->
<bean id="myTransactionManager"
class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="mySessionFactory"/>
</property>
</bean>
每一个对象能被Spring配置里的一个<bean>标记引用。bean“mySessionFactory”代表一个HibernateSessionFactory,“myTransactionManager”代表一个Hibernate transaction manager。transactionManger有sessionFactory的属性。 HibernateTransactionManager有一个为sessionFactory准备的setter和getter方法,它们是用来当Spring容器启动时的依赖注入。sessionFactory属性引用mySessionFactory。这两个对象在Spring容器初始化时将被连在一起。mySessionFactory有属性mappingResources,通过它的setter方法可以配置hibernate的映射文件。
配置了容器服务beans后,需要把业务服务对象和DAO对象连在一起。然后把这些对象连接到事务管理器。以下是在Spring配置文件里设置业务服务和DAO对象:
<bean id="projectService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="myTransactionManager"/>
</property>
<property name="target">
<ref local="projectTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="find*">
PROPAGATION_REQUIRED,readOnly,-ProjectException
</prop>
<prop key="save*">
PROPAGATION_REQUIRED,-ProjectException
</prop>
</props>
</property>
</bean>
TransactionProxyFactoryBean是一个处理声明事务操作和服务对象。可以通过设置transactionAttributes属性定义事务处理。其中属性target是一个对projectTarget的业务服务对象的引用。projectTarget定义使用哪个业务服务对象并有一个指向setProjectDAO()的属性。projectDAO是与持久层交流的DAO对象。以下是它们在配置文件中的定义:
<bean id="projectTarget" class="com.srmis.service. ProjectServiceImpl">
<property name="projectDAO">
<ref local="projectDAO"/>
</property>
</bean>
<bean id="projectDAO" class="com.srmis.dao. ProjectDAO">
<property name="sessionFactory">
<ref local="mySessionFactory"/>
</property>
</bean>
bean能以两种模式工作:singleton和prototype。默认的模式是singleton。当bean由Spring提供时,prototype模式允许创建bean的新实例。只有在每一个用户都需要自己的bean的拷贝时才使用prototype模式。
4.2.5 提供服务定位器
服务和DAO连接以后,需要把服务展现给其它层。可使用一个服务定位器模式类从Spring上下文中返回资源。也可以引用bean ID通过Spring来直接完成。
public abstract class BaseAction extends Action {
private IProjectService projectService;
public void setServlet(ActionServlet actionServlet) {
super.setServlet(actionServlet);
ServletContext servletContext = actionServlet. getServletContext();
WebApplicationContext wac =
WebApplicationContextUtils.getRequiredWeb
ApplicationContext( servletContext);
this.projectService = (IProjectService) wac.getBean ("projectService");
}
protected IProjectService getProjectService() {
return projectService;
}
}
4.2.6 用户接口层配置
在struts的配置文件struts-config.xml里检查Action配置。
<action path="/SaveNewProject" type= "com.srmis. action. SaveProjectAction"
name="ProjectForm" scope="request" validate="true" input="/NewProject.jsp">
<display-name>Save New Project</display-name>
<forward name="success" path="/ViewProject.jsp"/>
<forward name="failure" path="/NewProject.jsp"/>
</action>
SaveNewProject Action用来持久化从用户接口层提交的项目。
最后一个连接步骤是使表现层和业务层交互。服务层充当到业务逻辑和持久层的接口。下面是Struts中的SaveNewProject Action使用服务定位器调用一个业务方法:
public ActionForward execute( ActionMapping mapping,ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws java.lang.Exception {
ProjectForm oForm = (ProjectForm) form;
Project project=new Project();
getProjectService().saveNewProject(project);
oForm.setProject(project);
ActionMessages messages = new ActionMessages();
messages.add( ActionMessages. GLOBAL_ MESSAGE,
new ActionMessage("message.project.saved.success fully"));
saveMessages(request,messages);
return mapping.findForward("success");
}
5 结束语
多层架构可以解耦代码,允许添加新的代码组件,使应用更易文护。使用最主流的Spring+Struts+Hibernate架构的SpringSide技术能很好的解决这类的问题。SpringSide对J2EE进行裁减,组成了一个高效、松耦合的轻量级的架构,使层次明确,层次间耦合度低。在基于网络的科研管理系统开发过程中,其优势得到了很好的展现。如团队分工明确,协作编码与测试以及开发效率都有大幅度提高。
参考文献
[1] 邬继成. Struts 与 Hibernate实用教程[M]. 北京:电子工业出版社,712