联系方式: 微信:biyebang QQ: 629001810
摘要:
SMART系统是一个新型智能在线考试信息管理系统,该系统主要实现了学生在线考试与评估以及教师对学生在线考试信息的管理和维护。本文按照SMART系统的非功能性需求,基于Struts、Spring、Hibernate三种开源技术,构建了一个具有良好的可扩展性、可维护性、可靠性的系统框架。整个系统的框架分为三层,分别为表现层、业务层和持久层。 本系统的表现层是基于Struts作扩展设计,结合本系统的需求完成了自定义标签的封装,基本action接口的编写。在业务层则是采用单例模式设计与Spring的IoC模式相结合,实现了公共代理类的编写,各业务逻辑接口的封装。而在持久层的设计中则是采用基于现有持久层框架的实现模式,实现了对产生Session实例的封装,对常用数据库操作的封装。这样设计减少了耦合性且避免了生成大量的临时对象。
该系统框架能达到良好的可拓展性和维护性。它不仅仅适用这个系统的开发,可以应用于J2EE领域中基于SSH来架构的大部分B/S系统。
系统设计
图6系统总体框架示意图
如图1所示,在整个SMART系统的总体框架中表现层是结合J2EE领域的开源框架Struts来实现的,Struts能充分满足应用开发的需求,简单易用,该框架是基于MVC模式的来构建的,该模式将表达层分解为自包含的和可重用的几个部分,当用户通过浏览器发起HTTP请求时,该框架将利用其ActionForm将请求页面的非对象化的数据转化为对象,交由其对应Action来处理。基于MVC模式的整个交互的序列图如图7所示:
图7 MVC模式中的交互
开发人员利用该框架进行开发时,不用再自己实现全套MVC模式,节省了大量的开发时间。
如图1所示,在表现层与业务层之间利用一个公共代理类来完成交互,该代理类采用单例模式设计开发,在整个框架中起到了如下几点作用:
1. 减少耦合性
2. 避免生成大量的临时对象
在该代理类,实现一个对相应业务逻辑的处理方法,该方法的参数为一个封装好相应的页面数据对象、要调用的业务类的名称及该业务类中相应的处理方法名的类。
在该层中利用了Spring框架中的IoC模式(英文全名为Inversion of Control即反转模式),该模式类似于著名的好莱坞原则:“Don't call us,we'll callyou”,后被Martin Fowler改名为 DependencyInjection 依赖注射,也就是将类之间的关系通过第三方进行注射,不需要类自己去解决调用关系,实现了调用者和被调用者之间的解耦分离。IoC的引入并没有消除接口与实现类之间的联系,它的实质在于只是将这种联系转移了。在Spring的IoC实现中这关系被转移到相应的XML配置文件中,由Spring框架来提供对这种关系的依赖注入。其原理如图8所示:
图8 IoC模式在Spring中的依赖注入
在SMART系统的整体框架中的持久层,是采用基于现有持久层框架的实现模式,在这种模式中,将最为繁琐的基于JDBC的OR映射工作,交由第三方组件(本框架中采用开源的Hibernate)来完成,这样就会在对数据访问对象进行编码时,大大的简化了一些繁琐而又复杂的编码工作,只需要利用Hibernate提供的API,对持久化对象进行操作。在该持久层框架提供了优秀的性能优化机制,如内置的数据库连接池支持,PreparedStatement缓存、数据缓存等。这些优化机制的综合使用大大提升了系统的性能。
在SMART系统的持久层中,对一些常用的添加、删除、更新数据库操作进行了抽象封装。并在Hibernate中配置相应的数据库连接池实现。
图9基于现有持久层框架的实现模式
系统实现
在本系统中的表现层实现了一个抽象的BaseAction类,该类继承LookupDispatchAction,实现LookupDispatchAction类中的getKeyMethodMap方法,在方法中返回本系统中请求参数值与资源文件中参数值的键/值对。实现一些对于所有的Action都是有可能用到的公共方法。部分代码如下所示:
public abstract class BaseAction extends LookupDispatchAction {
//实现父类的方法
protected Map getKeyMethodMap() {
Map map = new HashMap();
map.put("button.save", "save");
map.put("button.cancel", "cancel");
…………………..
return map;
}
//统一的业务逻辑调用方法
protected Object call(Carrier vo) {
PublicProxy proxy = PublicProxy.getInstance();
Object obj = null;
try {
obj = proxy.process(vo);
} catch (ApplicationException ex) {
throw ex;
}
return obj;
}
//显示页面按钮
protected void showButton(String buttonName) {
Map btnMap = getButtonMap();
btnMap.put(buttonName, "true");
}
//隐藏页面按钮
protected void hideButton(String buttonName) {
Map btnMap = getButtonMap();
btnMap.put(buttonName, "false");
}
…………………………………
}
在本系统中的业务层实现了一个单例的PublicProxy类,系统中所有的表现层与业务层的交互都要通过这个类来实现。该类结合了Spring框架的相应的API对业务接口与其实现的对应关系的xml文件进行了解析,详见下面的类中的process方法中对xml文件的读取。
public class PublicProxy {
private static PublicProxy instance = null;
private static Object lock = new Object();
private PublicProxy() {
}
//返回唯一的实例
public static PublicProxy getInstance() {
if (instance == null) {
synchronized (lock) {
if (instance == null) {
instance = new PublicProxy();
}
}
}
return instance;
}
//相应的业务处理公共接口
public Object process(Carrier aop) {
Business business = null;
ApplicationContext context
= new ClassPathXmlApplicationContext("beans/*.xml");
business = (Business) context.getBean(aop.getBusiness());
return business.process(aop);
}
}
本系统的持久层是基于开源的Hibernate来实现的,结合Hibernate提供的API提供相应实现的部分代码如下所示:
public class HibernateSessionFactory {
…………………
private static final ThreadLocal thread = new ThreadLocal();
//打开一个新的session
public static Session openSession(boolean useCurrent) {
Session session = null;
if (useCurrent && thread.get() != null) {
session = (Session) thread.get();
}
if (session == null) {
try {
if (factory == null) {
factory = new Configuration().configure(
CONFIG_FILE_LOCATION).
buildSessionFactory();
}
session = factory.openSession();
//将session放入ThreadLocal中实现线程安全性设计
thread.set(session);
} catch (HibernateException ex) {
ex.printStackTrace();
}
}
return session;
}
………………
}
源文件
版权所有© 帮我毕业网 并保留所有权利