Java框架研究与实现_第1页
Java框架研究与实现_第2页
Java框架研究与实现_第3页
Java框架研究与实现_第4页
Java框架研究与实现_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

天津科技大学 2014 届 本科生 毕业论文 1 1 前言 1.1、课题研究的背景与意义 软件系统 不断地发展,直到今天可以说是非常复杂了,尤其是服务器端的软件,所涉及到的知识、内容和问题实在是太多太多啦,如果我们全都要自己亲力亲为也不是十分现实的事情。在具有多个层次的软件开发过程当中,框架凭借着其可重用和易扩展等诸多优点,并且软件组件经过了良好测试,已经越来越受到开发人员的喜爱。从别的角度考虑选择了运用别人开发出来的框架,就相当于是开发人员把基础性的工 作交给了别人来做,自己避开了繁杂的代码工程,只需要集中全部精力去完成核心的工作,那就是分析和构建系统业务 逻辑的应用 。以这个思想为基础,人们就将具有相同或相似类型的问题进行抽象,把相似的开发思路和解决途径抽象出来,提取得到一个应用框架。 Java 语言具有可移植、跨平台以及安全性等诸多的特性,应用越来越广泛,尤其是在网络应用中优势十分明显。 Java 应用程序框架有着什么样的意义呢?现如今微软的 Windows 操作系统一统桌面操作系统的天下,但是这并不能够否认其它桌面操作系统存在的事实,比如 Linux 、 MAC OS 以及新兴的 You、 Xin、eye OS 和 Ubuntu 等,其他操作系统的不断发展会动摇微软的霸权地位 13。考虑到各个操作系统百家齐放的情况,人们都是随意地挑选自己喜欢的操作系统,不同的电脑上可能运行着不同的操作系统,而不同的操作系统又有着它们自己独有的 API 函数,这就意味着运行在 Windows 操作系统上的应用程序就不能在其他的系统上运行,当然了其它的也不能在 Windows 上运行。开发应 用程序就会需要去投入更多的财力和人力来开发出可以基于不同操作系统的同类型的程序。这种情况之下, Java 语言的“一次编译,到处运行”的特性就使得其成为开发桌面应用程序的最佳选择。 Java 语言为应用程序提供的组件级支持具有强大功能,但是却并不能提供像 MFC 的 doc/view 一样的框架级的支持。如果是 C+程序员,利用 doc/view 很方便就可以开发出来一个桌面应用程序,而如果 Java程序员想要开发一个类似的程序却不得不从零开始。所以说 Java 应用程序框架就显得势在必行, Java 框架的研究和应用都会显 得非常重要。 在进行软件开发的整个过程当中,网络连接、内存、线程等一些稀有资源就可能需要对其进行管理,如果这些资源使用不当,就会在时间上或者空间上极大地限制软件的使用效率和性能。要想使得稀有资源得以充分利用,需要遵守的使用原则就是:尽最大可能去推迟资源的分配,然后尽最大可能去提前释放资源。因此开发人员在软件开发的过程中采用共享模式,在时间和空间上尽量去复用这些稀有资源。 计算机网络的飞速发展使得人们更加高标准严要求地去进行网络资源的共天津科技大学 2014 届 本科生 毕业论文 2 享。在基于 Java 语言并且需要进行和数据库有关操作的 Web 应用开发当中, 用户对数据库中数据的访问必定是十分地频繁。访问数据就需要先建立数据库连接,连接的建立会耗费巨大的系统开销,频繁地进行连接建立和关闭操作或者单单是不断地去创建新的连接就已经让服务器难以承受。连接数量的失控也会降低服务器的性能,甚至会造成服务器崩溃。这一切的问题都迫切需要引入一种高效率的资源管理机制来解决,数据库连接池就及时的出现啦。 1.2、本文作的工作 本文首先从整体说起,介绍了框架的整体概念,框架开发应用的特点与重要意义。然后对主要的 Java 框架进行研究和介绍,主要包括 S2SH 框架、 JFreeChart、C3P0、 DBCP, 最终使用 MyEclipse 软件实现了一个小型的 Java 框架 数据库连接池。 其中重点介绍的是数据库连接池的实现,先从传统的 JDBC 数据库连接着手,介绍传统模式的工作原理及其存在的缺陷,然后基于 JDBC 连接不断对其进行功能的优化,最终得到高效资源管理的数据库连接池。为了突出连接池的优越性能,建立相同连接次数,进行相同的操作,比较两种方式的时间代价。并且对连接池的部分优化进行测试,验证最大连接数、最大使用次数和 close 方法的拦截。 天津科技大学 2014 届 本科生 毕业论文 3 2 Java 框架的研 究 2.1、框架概述 框架( Framework)是整个系统或部分系统为了实现可重用而形成的一种设计,是实现抽象的 构件 和构件实例进行交互的一种方法。框架可以说是一个半成品,只需再修改加工就可以成品,是可以供你选用然后完成你自己系统的一组 组件 ,可以把这个过程想象成你使用别人搭建好的一个舞台来进行表演。 同时框架一般情况下是比较成熟的,在不断升级中的 软件 。 选择使用框架可以说是用“自由”去换取“方便”,系统的开发人员只需要也只能在框架所限制的要求以内来完成一些业务组件,框架会统一管理这些组件并帮助相互之间进行协调 1。在 Web 框架中,这种自由换方便的具体表现是:业务逻辑和显示逻辑都要按照规则放置,然后按照要求去组织和配合,这种规则必须要遵守,而不能够随心所欲。当然我们收获的就是具有良好结构,可靠质量的Web 应 用。成熟、健壮的框架能够把系统细枝末节的问题处理的很好,事务处理,安全性保证和数据流控制等一系列问题框架都可以解决。 可以为应用程序的开发人员带来很多的便利: (1)通过提供这么一个基础设施,就能够减轻开发人员代码编写,进行测试以及反复调试的巨大工作量,而只用编写、测试、调试基础之上的特有的代码,从而使得重复开发的巨大工作量大幅减少,开发的周期大幅缩短,开发成本也降低不少。 (2)以同一个框架为基础创建的不同的应用程序或系统,它们具有相同的结构,这样就便于相互之间的集成。同时相对于用不同设计方案创建 的应用程序,框架的长处就是更加容易进行维护。 (3)便于同一个项目中的工作人员进行并行工作,约定俗成的规则可以让他们配合的更加默契,也可以变向地缩短开发的周期。 (4)还有就是框架一般都是经过很多人使用跟测试的,从而保证了好的结构和更强的扩展性,而且它还处在在不断地升级过程中,升级的代码可以给你带来的源源不断的便利。 2.2、软件体系中框架的地位 框架一般情况下是处在低层次的应用平台(比如 J2EE)和高层次的业务逻辑之间的一个 软件层 ,框架本身也是一个可以运行的系统。设计文档、接口、抽象类、组件还有类库共同组成了框架。 5个要素之间的关系 14如图 2-1所示。 天津科技大学 2014 届 本科生 毕业论文 4 反映 实现 实现 继承 组合 2.2.1、使用框架开发具有很多优点 重用无疑会是框架提供的最大便利。 面向对象 系统所能尽最大可能去获取到的复用的方式就是使用框架了,一个大型的应用系统往往就是由多个层次通力协作的框架组合得到的。框架之所以从已有 组件 库中选择建立应用会显得那么容易,是因为框架能够重用代码,而且这些组件采用的都是框架统一定义的接口,就使得组件之间的通信变得十分简单。 框架可以对设计进行重用。框架能都提供具有可重用功能的抽象的算法和更高层次的设计,还 可以将大的系统进行分解,得到更小的组件,同时可以描述组件之间的内部接口。由于这些标准接口的存在,就可以在这个基础之上通过组合建立各种各样的系统。只要是能够符合接口的规范,新的组件就能够应用到框架当中,就可以重用组件的设计。 框架还可以对分析进行重用。试想一下,所有的开发人员都能够按照框架的思维来进行分析,那样就可以把框架进行同样的划分,采用的解决方法也会是相似的,一个项目里的工作人员可以更加方便地进行沟通。 框架开发使得领域之内的软件的结构一致性更好;所建立的系统开放性更好;重用代码的增多使得软件的生产效率 提高,整体的质量得到增强;需求分析做得更加有条有理,软件设计人员可以储存更加丰富的经验;参数化的框架使得系统不管是适应性还是灵活性都更好。 2.2.2、框架对软件开发有着重要的意义 ( 1)积累知识 设计文档 接口 抽象类 组件 类库 图 2-1 框架组成要素之间的关系 天津科技大学 2014 届 本科生 毕业论文 5 框架的价值中最核心的是对知识的积累。虽说软件开发是一项知识性的活动,但是知识存在的是人的大脑之中,对其进行积累是很难进行的。在软件整个开发过程中,代码是最确定的,计算机对于同一段代码运行之后只会得出一个相同的结果,不同的人理解也不会有所不同。所以对知识的积累要从对代码的积累开始。而框架就是通过这种思维得到的,框架 之中包含有大量的代码,这些代码描述的是一定领域之中对某个特定问题的抽象概念以及这些抽象概念之间的关系。所以说框架能够达到积累知识的目的。但是单纯的代码层次太低,如果开发人员只是通过代码来理解框架,那也太困难太不现实了。所以要有设计文档、UML 图、模型等部件来帮助框架开发人员更加方便的理解代码。 ( 2)保护资产 积累知识原本就属于一项保护资产的工作,另外就是确保软件组织(尤其对于企业来说)这些知识的学习都是经过合法授权的。举例来说,任何组织最不愿看到的都会是知识非法外流,把知识积累成框架的形式可以帮助解决这个 问题。框架可以选择以源代码的形式对外发布,以库形式发布也是一个选择,这样不同种类的框架用户就可以选择不同的形式,可以达到权限控制的效果。 ( 3)鼓励重用 重用对框架来说是特别注重的。在进行软件开发的过程中要把框架做为发开发方式中的核心,应用框架,并根据现实情况的变化跟需要不断对框架进行改进。重用在这个完善的过程中就发挥了它的作用。 ( 4)可以对架构进行优化 框架之所以称之为框架,正是因为它实现了重用。与此同时框架代表的是一种优秀的软件架构。框架首先定义了扩展的方式,然后形成了使用的规范。这一切就是软件开发保 持整体架构稳定性和一致性的重要保证。 2.3、当前流行 Java 框架的简要介绍 1、 S2SH 框架 S2SH 是一个由 Struts 2+Spring+Hibernate 集合而成 的 Web 应用程序 框架,是当下被广泛使用的一种开源的框架。 Struts 框架是由 Craig R.McClanahan 在 2000年设计 和开发的一种基于 J2EE 平台同时实现了 MVC 设计模式的框架,采用面向对象的设计为 Java 社区提供了一个标准的、通用的 Web 应用框架。 Struts 框架不仅兼有组件模块化、灵活多变以及重用的优势,而且使得开发采用 MVC 模式的 Web 应用 程序 的过程得到了简化。 Struts 2是在 Struts 和 WebWork 技术的基础之上通过合并而得到的一种全新的框架。 Struts 2与 Struts 在 体系结构 上具有很大的差别, Struts 2的核心是WebWork,通过使用拦截器的机制来对用户的请求进行处理,这样的操作使得业天津科技大学 2014 届 本科生 毕业论文 6 务逻辑控制器完全摆脱 Servlet API 的束缚,因此从字面上看 Struts 2是 Struts 的升级,而其实是 WebWork 升级后的产品。 Struts2框架的工作原 理 2如图 2-2: ( 1)客户端提交了一个 HTTP 的请求,这个请求首先需要通过一些个过滤器,主要包含 ActionContextCleanUp、其他过滤器还有 FilterDispatcher 三层 Filter。 ( 2) FilterDispatcher 是控制器的核心所在,紧接着需要调用 FilterDispatcher 对ActionMapper 进行询问,由此来判定该请求有没有调用 Action 的必要。 ( 3)如果需要去调用, FilterDispatcher 就把请求的处理权交给到 ActionProxy 手上, ActionProxy 会透过 Configuration Manager 和 Struts.xml 对 框架的配置文件进行询问,然后找到需要调用的 Action 类 。 (4)然后 ActionProxy 会实例化一个 ActionInvocation,于此同时 ActionInvocation HTTP 请求 ActionContextCleanUp 其他过滤器 FilterDispatcher ActionProxy Configuration Manager Struts.xml Action Invocation 拦截器 1 拦截器 3 拦截器 2 拦截器 3 Action Result 拦截器 2 拦截器 1 ActionMapper 标签库 视图模板、 JSP、 FreeMarker 等 HTTP 响应 图 2-2 Struts 2 的工作流程 天津科技大学 2014 届 本科生 毕业论文 7 会通过代理模式的使用来调用 Action,在对 Action 进行调用的整个过程的前后,都会需要去调用相关的拦截器。 ( 5) Action 执行完成以后, ActionInvocation 就会根据 struts.xml 中的配置文件找到所需要的返回结果。这个 返回结果通常是一个需要被表示出来的 JSP 抑或是FreeMarker 的模版。在这个过程当中还允许使用从 Struts 2框架中继承来的标签。 Spring 是由 Rod Johnson 创建,源自于 Expert One-on-One J2EE 设计与开发 3一书中的代码,从 2003年兴起而来的一个开源的轻量级 Java 开发框架,为的是降低企业级应用开发的复杂性。通过使用基本的 JavaBean, Spring 完成了以前只可能由 EJB 完成的事情。更重要的是 Spring 的用途不仅仅局限于服务器端的开发,从 易测试 、简单干净、 低耦合 和便于管理的角度考虑问题,所有的 Java应用都能够从 Spring 框架的应用中受益匪浅。 Hibernate 是由 Gavin King 开发出来的一个源代码开放的 对象关系型数据映射 的框架, 它对 JDBC 进行了轻量级的对象封装,在 Java 应用和关系型数据库之间架起了一条“桥梁”,把由对象模型表示出来的 Java 对象对应到关系数据库表中,使得 Java 的开发人员操控数据库的时候能够自由地运用对象 编程 的思维。 在任何使用 JDBC 的场合下都可以应用 Hibernate,其中就包括在 Java 的客户端程序中和在 Servlet/JSP 的 Web 应用中的使用。除了对 Java 对象到关系数据库表的映射进行管理之外, Hibernate 还提供了一些获取数据和进行数据查询的方法,极大地减少了开发过程当中人工使用 SQL 和 JDBC 对数据进行处理所花费的时间,非常成功地完成了数据持久化的目标任务。 2、 JFreeChart JFreeChart 是运用在 Java 平台上的一个开放式的绘制图表的类库。它完全是由 Java 语言编写而成的,是为了 applications、 applets、 servlets 以及 JSP 等的使用所设计的。 JFreeChart 可以用来生成饼状图( pie charts)、 时序图 ( time series)、柱状图( bar charts)、 散点图 ( scatter plots)、 甘特图 ( Gantt charts)等一系列的图表,并且可以产生 PNG 和 JPEG 格式 的图像文件输出,还可以关联到 PDF 和Excel。具有性能稳定、轻量级和功能强大的优点,是一种很好的 Java 图形的解决方案,基本上能够满足图形方面的需求。同时 API 处理简单也就意味着用户能够轻松上手,生成的图表运行起来也会很流畅。 JFreeChart 存在的缺点就是单单适合图片的生成,并且文字、图片都不是那么的清晰,还会需要进行一些调整,因此会显得比较麻烦。 3、 C3P0 C3P0是一个开源了的 JDBC 连接池 ,它主要的功能是实现了数据源和JNDI(即 Java Naming and Directory Interface,也即 Java 命名和目录接口 ) 15的捆绑,可以支持 JDBC3规范和 JDBC2规范标准的扩展。 C3P0连接池的独到之处就天津科技大学 2014 届 本科生 毕业论文 8 是具有自动回收空闲连接的功能,目前 Hibernate, Spring 等 开源项目 都使用的有 C3P0连接池。 4、 DBCP DBCP(DataBase Connection Pool,即 数据库连接池 )属于 Apache 上面一个Java 连接池的项目,同时也是应用于 Tomcat 的一个连接池组件。在单独使用DBCP 的时候还会需要有 3个 Jar 包: commons-dbcp.jar、 commons-pool.jar 和commons-collections.jar。考虑到建立数据库连接的操作是一个系统开销大且费时的行为,所以预先创建一些个数据库连 接放到连接池中,储存在内存之中,应用程序请求数据库访问需要建立数据库连接的时候就直接到连接池中取一个连接,连接使用完毕以后还要放回到连接池中。与 C3P0连接池相比, DBCP 不具有自动回收空闲连接的功能。 天津科技大学 2014 届 本科生 毕业论文 9 3 数据库连接池的实现原理 3.1、基于 JDBC 的传统数据库访问机制 JDBC(Java Database Connectivity)也即 Java 数据库连接,是一种由 Java 语言编写的接口和 类组成的可以用于直接执行 SQL(Structured Query Language)语句的 Java API。它是 J2SE 的一部分,主要功能为不同的关系型数据库(如 MySQL、Oracle、 DB2、 SQL Server 等等)提供一致的访问机制,通过 JDBC 可以访问多种数据源 ,从关系型数据库到文件系统都没有问题。 JDBC 主要是由 Java.sql 和 Javax.sql 两个包组成,其中 Java.sql 包提供了一组可以用来访问和处理数据源中数据的 API;而 Javax.sql 包提供的是一组在服务器端可以用来访问和处理数 据源的 API11。 JDBC 能够为数据库的开发人员提供出来一个具有统一标准的 API(Application Programming Interface,就是应用程序编程接口 ), JDBC 作为这样一个 低级 的接口,就说明了它可以用来直接调用 SQL 命令。在这一方面它表现出了比其它的 数据库 连接 API 更好的优势 ,同时它也被设计成一种基础接口,以此为基础可以建立起来更加高级的接口还有工具。所谓的高级接口是 指用户友好型的接口,它使用的是一种让用户更容易理解使用起来更为方便的 API,这种 API 在后台然后再被转换成类似 JDBC 这样的低级接口,使得数据库的分开发人员可以使用纯的 Java API 来编写数据库应用开发程序。 JDBC 的应用使得向各种关系型数据库发送 SQL 语句的操作变成一件容易的事。换句话说,有了 JDBC API,就不需要为访问 MySQL 数据库写一个程序,为了访问 Oracle 数据库再专门写一个程序,程序员就只需要使用 JDBC API编写一个程序就可以通用了,它就可以向相对应的数据库发送 SQL 调用命令 12。 3.1.1、 JDBC 驱动介绍 JDBC API 包含有两种最主要的接口:一种是为应用程序开发人员提供的API,另一种是为驱动开发人员提供的驱动 API。这样应用程序就可以通过 JDBC API 使用 JDBC 技术的驱动来访问数据库。 JDBC 包含有四种类型的驱动 4: 类型一是 JDBC-ODBC 桥 +ODBC 驱动,如图 3-1 左半边所示,这样的组合是通过 ODBC 驱动提供了 JDBC 访问。在大多数的情况之下 ODBC 二进制码是数据库的客户端库,必须被加载到每一个正在使用 JDBC-ODBC 桥的客户机。Sun 公司提供过一 个 JDBC-ODBC 桥驱动 ,但是只是被作为实验性使用或是手边实在没有其它驱动的情况下,才不得已使用这个驱动。在实际的应用过程中,这种驱动是不会被使用的。 类型二是本地化的同时支持 Java 技术的 API,如图 3-1 右半边所示,这种类型二的驱动就将 JDBC 进行调用转化,是特定的数据库厂商自己开发的 API。需要注意的是,和桥驱动一样这种类型的驱动也要求每台客户机都要把相应的二进天津科技大学 2014 届 本科生 毕业论文 10 制码加载进来。 Java 应用程序 JDBC API JDBC 驱动管理器 或数据源对象 JDBC- ODBC 桥驱动 非纯 Java JDBC 驱动 ODBC 数据库客户库 数据库客户库 数据库服务器 数据库服务器 图 3-1 JDBC 驱动类型一和类型二 Java 应用程序 JDBC API JDBC 驱动管理器 或数据源对象 纯 Java JDBC 驱 动 纯 Java JDBC 驱动 数据库服务器 数据库中间件 数据库服务器 图 3-2 JDBC 驱动类型三和类型四 天津科技大学 2014 届 本科生 毕业论文 11 JDBC 驱动类型一和类型二都不是基于纯 Java JDBC 的驱动,它们存在一个共同的缺点,那就是都需要在每台客房机端加载相对应的二进制码。所以在现实的应用过程当中,这两种类型的驱动都不是很经常性的使用,特别是对于JDBC-ODBC 桥驱动来说,它的性能甚至还不如特定数据库厂商提供的驱动好用。 类型三是直接连接到数据库的纯 Java 驱动,如图 3-2 左半边所示,类型三的驱动是调用 JDBC 转化成由数据库管理系统直接使用的网络协议,这样就可以从客户机直接调用数据库管理系统的服务器,紧接着就是为内部网的访问提供了一个切实可行的解决方案。 类型四是纯 Java 驱动,主要面向 的是数据库的中间件,如图 3-2 右半边所示,这种类型的驱动将 JDBC 调用转化为中间件所使用的协议,然后这种协议又被中间件服务器转化为数据库管理系统所使用的协议。数据库中间件可以为各种不同的数据库提供连接服务。 3.1.2、 JDBC 具有的优点 JDBC 是所有基于 Java 的应用中最常用的连接数据库方法,基于优点众多: ( 1) JDBC 技术的使用使得业务逻辑不会受到任何特定架构的束缚,能够继续使用已安装的数据库,能够很方便地访问信息,即使是这些信息存储在不同的数据库管理系统中也没有问题。 ( 2)使用 Java API 和 JDBC API 能够应用程序的开发得到简化,使得开发得以更加方便高效地进行。 JDBC 可以隐藏许多数据访问的复杂工作,这样一来大多数对于程序员而言十分困难的工作,都将由 JDBC 在后台不知不觉中地完成,大量地减轻了程序员身上的重担。 ( 3) JDBC API 的使用就使得客户端完全不需要进行任何的配置。使用由Java 语言编写的驱动 ,使得在构建数据库连接时需要的所有的信息,将完全由JDBC URL 或者由 JNDI 注册在命名服务中的数据源的对象来操作完成。 JNDI为程序开发人员提供了查找与访问各种各样命名、目录的统一的接 口,通过一个名称就可以查找到所需要的对象。 3.1.3、 JDBC 存在的一些弊端 在使用 Java 语言开发的基于数据库的 Web 应用中,一般情况下都会使用JDBC 来连接数据库进行交互。 Java 传统模式访问数据库时需要以下步骤:首先需要注册所使用数据库的驱动程序,然后在主程序中通过 JDBC 搭建起数据库连接,紧接着执行 SQL 语句进行增删改查操作,最后连接使用完之后要关闭数据库连接释放占有的资源。对于小型的 Web 应用来说,对数据库的访问不会特别的频繁,使用这种传统的方式还勉强可以接受;但是如果对于大型的 Web 应用,这种 方式就会暴露出一系列的漏洞: 天津科技大学 2014 届 本科生 毕业论文 12 ( 1) 用户每一次发送 Web 访问请求都需要建立新的数据库连接,而大型Web 应用需要非常频繁地建立和关闭数据库连接。建立数据库连接不仅需要占用系统的通讯和内存资源,而且大多还需要验证用户和安全上下文( Context) 配置这些任务,占用和消耗了一次访问大多数的资源和时间,频繁的进行操作会大大地加重了系统的负担,并且还会降低数据库服务器的性能。 ( 2) 对于每一次建立的数据库连接,使用完毕之后必须要断开连接。如果程序出现异常或者是操作出现问题而导致某一些连接不能正常地关闭 ,这会导致数据库系统中的内存 出现泄露 ,还有可能导致系统崩溃,最终的结果极有可能是被迫重启数据库来恢复系统。所以必须要对每一次的数据库连接进行管理 ,以确保它们能够被正常地关闭,但是这一切对于程序员来说显然是极难实现的。 ( 3) 这种传统模式不能够控制被创建的连接数量,系统的资源就会被毫无保留地分配出去,如果建立的连接数过多就很可能会导致系统内存泄露,进而可能造成服务器的全面崩溃。在与数据库相关联的 Web 应用中,建立数据库连接是既费时费力又代价巨大的操作,频繁地建立连接和关闭连接会造成很大的性能开销,就会影响到整个系统的效率,这通常就是限制网站速 度的瓶颈因素。 很显然,使用传统的的模式来实现对数据库的连接访问可以说已经远不能满足实际的需求了,因此就要求必须做出改进。比较有效合理的对策就是对数据库连接进行复用从而实现共享,那就是建立一个更加高效的资源管理机制 数据库连接池。通过数据库连接池可以提供出来有效的连接、分配和使用的策略,一方面提供快速、合理并且有效的连接服务,另一方面又可以避免频繁的建立关闭连接所带来的巨大系统开销。 3.2、数据库连接池的原理 连接池顾名思义就是“缓冲存储池”,也即连接对象的集合。其最基本的思想是:复用建立的连接,建立一 个数据库连接池,采用一套完整的连接的使用、分配以及管理的策略,以此来保证这个连接池中存放的连接能够获得高效率并且安全性高的复用,从而避免数据库连接被频繁建立和关闭所带来的巨大的系统开销。除此之外,由于对 JDBC 中原始的连接进行了封装的处理,更加便于数据库应用(特别是对于事务处理来说)来使用连接,极大地提高了开发的效率,此时正是由于这个封装层的运用,划清了数据库应用自身的处理逻辑和具体的数据库访问逻辑之间的界限,使得数据库应用本身得以成功复用 7。 当一个用户向数据库提出访问请求时,数据库连接池就会从池 中分配一个数据库连接给该用户使用;当该用户数据库访问结束的时候,他被分配使用的连接将被重新放回到连接池中,以供他人继续使用而不是被销毁,同时连接的创建与关闭都是由连接池自身来进行管理的。数据库连接池最初的模型 6如图 3-3 所示。 天津科技大学 2014 届 本科生 毕业论文 13 取得连接 放回连接 连接池最主要由连接池的建立、连接池中连接的使用和管理以及连接池的关闭三个环节组成。 1、连接 池的建立 应用程序中建立的连接池大多都属于是静态的。静态的连接池指的就是连接池当中存放的连接是在系统初始化的时候就已经创建好的,并且不允许随意地关闭。 Java 有许多容器类都可以非常方便地实现连接池的功能,例如: Stack、Servlet、 Vector、 JavaBean 等等。在系统进行初始化的时候,需要根据与之相应的配置文件创建一些连接放置到连接池中,以便需要使用连接时能够从连接池中及时地获取,这样做就可以降低频繁地建立和关闭连接所造成的巨大系统开销。 在实际的实现过程中 ,通常是把数据库连接作为一个对象存 储在这些容器类对象中 (即连接池 )。一般说来,一个数据库连接池应该具备以下一些功能: (1)能够存储若干个有效的连接; (2)可以验证连接是否正常; (3)对于一个数据库访问请求 ,能够直接从连接池中获得一个连接; (4)如果数据库连接池当前不存在空闲的连接,同时当前连接数还没有达到预先设置的最大连接数,就可以再创建新的数据库连接来使用; (5)能够取回使用过的连接; (6)连接池关闭时能够关闭池中所有的连接。 2、连接池的管理 连接池 Servelt, JavaBea, SQL 操作 图 3-3 连接池模型 天津科技大学 2014 届 本科生 毕业论文 14 连接池的管理策略就是连接池机制的核心所在。连接池建立成功了之后,怎样对连接池中存放 的连接进行管理,怎样去处理好连接的分配与释放,这些都是对系统的性能有着重大影响的关键问题。通常的情况之下连接池中会分有空闲的队列和已分配出去的队列,空闲队列中存放的是未分配出去的连接,已分配出去的队列中存放正在被占用着的连接。连接的合理分配与及时释放都能够提高连接的复用效果,不仅能够降低系统不断建立新连接的巨大开销,同时也会加快用户进行访问的速度。 连接池的分配、释放策略对于连接的有效复用可以说是至关的重要,我们采用一个常用的设计模式 16: Reference Counting(引用记数)。这个设计模式在 复用资源方面的运用都非常的广泛,因此可以把这种思维运用到连接资源的分配与释放上面,让每一个数据库连接都对应于一个引用记数,目的是记录连接使用的数量。 当用户发出数据库连接请求时,首先要查看连接池当前是否存在有空闲着的连接(指的是当前还没有被分配出去的等待分配的连接)。如果存在就把连接分配给用户并把这个连接标记成分配状态,同时引用计数要加 1,并且注册到已分配队列之中。若连接池中当前不存在空闲的连接,则先查看该连接池的连接数是否已经达到设定的最大连接数 maxCount,如果还没有达到就创建一个新的连接给请求访 问的用户并设置其为已分配状态即可 ;如果当前连接数已经达到了最大连接数就只能等待其它线程释放连接以后才可以获取连接,这个等待过程就按照设定的最大等待时间进行等待,如果等待设定的时间之后池中仍然没有出现空闲的连接,就抛出无空闲连接的警告信息给用户说明此次请求无效。 当用户要释放数据库连接时,先判断该连接的引用记数是否超过了预先设定的最大值,如果已经超过就彻底删除该连接,然后需要判断当前连接池内存在的总的连接数量是否小于连接池的初始化连接数 initCount,若小于就创建新的连接填充连接池;如果没有超过规定的 最大使用次数就把连接重新放回到连接池中,等待连接的线程就可以获取连接进行再次复用。 3、连接池的关闭 退出应用程序的时侯,需要把连接池关闭,这就要求把连接池建立之时申请的连接对象统统归还给数据库,也即关闭所有建立的数据库连接,这个过程与连接池的建立的过程正好是一个逆向的过程。 3.3、连接池几个关键技术的介绍 在 Web 应用开发的过程中,为了保证数据库连接复用高效和安全的实现,下面的几个关键技术将会起到举足轻重的作用。 1、连接池大小的确定。在创建数据库连接池时,池中到底应该放置多少数量的连接,才能够使得系统 的性能达到最佳状态呢?系统可以通过采取设置和调天津科技大学 2014 届 本科生 毕业论文 15 整初始化连接数与最大连接数的方法来对连接池中连接的数量进行控制。初始化连接数顾名思义就是系统启动之时连接池所创建的连接的数量。为了确保连接池中的初始化连接数所采取的策略分为动态和静态两种策略。动态的策略是每隔一段时间才会对连接池进行检查,一旦发现池中连接的数量小于初始化连接数,就创建相应数量的新的连接放进去,以此确保连接池的正常运转所需的连接数。静态的策略是等到空闲连接不够用的时侯才去检查。而最大连接数是连接池中设定的允许创建连接的最大数量,具体值设置为多少,就 要看系统的访问量而定,需要通过反复进行测试,来找到最佳点。一般的策略是:首先设置一个相对较大的连接池,然后再逐步减少它的大小来寻求这个最佳点,通常情况下以 CPU 的占用率在 75%到 85%之间同时用户负载正常为宜。 2、事务处理。事务是应用程序当中一系列严密的操作,所有的操作都必须遵循 All-All-Nothing的原则,即所有的操作必须成功完成,否则在每个操作中所作的所有更改就都会被依次撤销。事务的原子特性要求一个事务中进行的一系列操作要么全部都成功完成,要么一个都不能做,不能是一个半吊子。在 Java语言 中, Connection 类自身就支持事务,可以把 Connection 的属性 AutoCommit设置成 false,然后再通过调用 commit 或 rollback 来实现。要是简单的使用复用连接的策略,会出现一系列的问题,因为我们没有办法去控制属于同一个事务的多个不同数据库操作方法,有可能这些数据库操作是在多个不同连接上来进行的,并且这些连接还存在有被其他非事务的方法复用的可能性。但是如果想要更加高效安全地进行连接复用,就必须提供支持事务的机制。具体表现为:使用显式的事务支持的方法,每一个事务占用一个连接。这种独占 连接的方式可以降低事务处理的复杂程度,并且不会对连接的复用造成任何影响。 3、封装。从上面的论述我们不难看出,考虑连接分配和释放,一般的数据库方法跟事务处理的方法是不一样的,为了便于使用接口,我们把事务连接和普通连接进行了封装。并且利用了 Java 中面向对象设计的多态特性,把普通的连接和事务连接都实现了一个 Connection 接口,至于接口中方法的定义,就需要根据自己具体的特点然后做出不同的实现,对连接采取这样的处理上就显得非常的一致。 4、并发。为了使连接的管理具有更加强大的通用性,多线程环境的复杂情况就必须考虑其中,也就是考虑并发的问题。对于多线程的环境,必须要考虑的问题就是连接管理自身数据一致性和连接内部数据一致性的保证。 Java 在这方面就可以提供很好的技术支持,可以通过加锁(通过函数 synchronized 来实现)来控制访问的顺序,由此就可以保证连接管理的线程安全。 5、实现多个数据库服务器的连接。在实际的应用过程中,应用程序不会仅仅局限于使用一个数据库,通常情况下都会需要去访问多个不同的数据库。所以天津科技大学 2014 届 本科生 毕业论文 16 怎样能够使用同一个连接池去对不同的数据库进行访问,是需要解决的问题核心。通常情况下可以采取的方法是 :通过设置一个连接池管理服务器来专门用于连接池的管理工作,这个管理器应该具有以下的功能: (1)可以根据初始设置的不同创建出不同的连接池; (2)能够存储多个不同的连接池,不同的连接池中存储不同功能的连接; (3)可以根据请求的不同向用户提供不同连接池中的连接; (4)能够把使用完的连接放回到与之相应的连接池中去; (5)应用程序关闭之后能够释放所有连接池中的连接。 天津科技大学 2014 届 本科生 毕业论文 17 4 数据库连接池的具体实现 4.1、通过 JDBC 建立数据库连接的实现过程 4.1.1、 JDBC 连接数据库的最基本步骤 : 图 4-1 JDBC 建立数据库连接的基本步骤 如上图 4-1 是 JDBC 建立数据库连接的基本步骤 8,主要包含下面 6 个步骤。 ( 1)注册驱动 。 以上两种方式是比较常用的注册驱动的方法,第二 种方式是先根据类的名字把类装载到虚拟机中,然后需要调用静态代码块把驱动类放入到由 DriverManager 管理的驱动列表中;第一种方式是创建了类的实例。两种方式比较起来,前者比较依赖 MySQL 驱动,一旦离开将不能通过编译;后者则显得更加灵活。因此在开发过程中大多选择第二种方式进行驱动的注册。 ( 2)建立连接 。 url用于找到相应的数据库 , 而用户名和密码是对用户访问的权限进行设置。有了 url,用户名和密码就可以通过 DriverManager建立起连接。 ( 3)创建语句 。 连接建立起来以后,就要创建语句。如果把连 接比作一个桥梁的话,那么此处创建的语句就好比是一辆货车,必须通过连接这座桥梁才能够到达对岸运送货物。运送的是 SQL语句,然后可以把所需的结果运回。 ( 4) 执行 SQL语句,得到所需的结果集。这个过程就好像是货车从河对岸天津科技大学 2014 届 本科生 毕业论文 18 运回了我们想要的货物。 ( 5)结果处理 。 把结果集中的结果打印出来,按行读取,然后每一行是按列读取。这个过程就好像是按照一定的顺序把运回的货物卸下了货车。 ( 6)释放占有的资源 。 资源释放的顺序和建立时的顺序正好相反。这个过程就好比我们从学校外面回宿舍,先进的是学校大门,然后进宿舍门;出去的时候就是 要先出宿舍门,然后才是出校门。 以上 只 是个简单的过程,还存在着一些问题,比如驱动的注册只需要做一次就好了,如果把上面过程当做一个连接模板,那么每创建一次连接就会注册一次,显然不太合理。连接的建立包含参数 url、用户名和密码,如果涉及到参数的修改,程序内部所涉及到的地方就会都需要修改,如果没有全部修改,还会出现错误,因此会显得非常麻烦。 4.1.2、对基本 JDBC 连接的优化 下面就将对上面的 JDBC连接过程进行优化,解决上面提到的一系列问题。解决的思想就是面向对象封装的思想,把烦杂的操作都给封装起来,以使得连 接操作更加严谨合理。这里可以通过创建一个工具类 Utils,来把注册驱动、建立连接和关闭连接几个步骤封装起来 10。 下图 4-2是工具类 Utils的主要代码: 图 4-2 工具类 Utils 的主要代码 天津科技大学 2014 届 本科生 毕业论文 19 首先工具类 Utils的创建不是为了用于继承,所以就禁止掉继承;构造方法采用的是私有的方法限制实例的构造; url、用户名和密码这些属性都定义为私有,这样自己修改就不会影响到别人创建连接的操作。其次把加载驱动这部分放到了静态代码块中,就使得驱动的注册只会做一次。 try 和 catch的使用保护驱动注册的顺利进行,否则就会抛出初始化的错误。最后是连接的关闭, try, finally保证无论发生任何异常,连接都可以正常关闭。 Utils工具类创建完成之后,连接的过程就变得简单了 9。 下图 4-3是部分操作封装到 Utils工具类 以后的连接过程 。 图 4-3 封装后的连接过程 天津科技大学 2014 届 本科生 毕业论文 20 图 4-4 MySQL中的 xinke表数据 图 4-5 连接建立成功获取数据库数据 天津科技大学 2014 届 本科生 毕业论文 21 然后在 MySQL数据库中插入数据 17,如图 4-4显示的是 MySQL数据库中 tust下一个 xinke 表的数据,建立连接对其执行查询操作,检验连接建立是否成功。由图 4-5可以看到连接建立并成功获取数据。 4.2、优化与测试 4.2.1、耗时比较 测试 JDBC连接建立 和 关闭循环 100次的时间代价。 图 4-6 耗时测试代码 图 4-7 JDBC 连接 100次耗时测试 结果 天津科技大学 2014 届 本科生 毕业论文 22 图 4-6是建立 100次连接耗时测试的代码, 图 4-7是 JDBC连接 100次耗时测试结果。 JDBC建立的每一个连接都是使用之后直接关闭,因此每一个连接都不一样,连接 100次花费时间为 893ms。 接下来要着手数据库连接池的建立。连接池的核心思想就是要实现对连接的复用,这里建立一个集合,存放 一些连接,然后需要使用连接就从集合中取一个,用完之后再放回到集合中,以供他人使用。考虑到集合中的连接需要频繁的插入和删除,因此这个集合就用链表来实现。首先初始化一个链表,建立部分连接放入链表,需要连接的时候就从链表首部取一个,使用完之后插入到链表尾部。 下图 4-8是通过构建数据源存放连接建立起连接池的代码。 图 4-8 数据库连接池的构建代码 天津科技大学 2014 届 本科生 毕业论文 23 图 4-9 数据库连接池 连接 100次耗时测试 结果 如图 4-9,以上连接的建立都是按照顺序获取和释放,因此对于初始化的 5个连接来说,创建的 100个连接就是每隔 5个 都一模一样。跟 JDBC连接的 100次相比,进行了相同的操作,但是耗时却只有 323ms,因此说数据库连接池的优势就显而易见啦! 4.2.2、并发的控制 但是在现实的 Web应用之中,线程的并发操作非常常见,因此就要考虑几个线程并发操作来获取连接的情况,如何才能避免冲突,保证每个线程取到不同的连接?同时要考虑到连接数量的问题,当有连接请求时池中是否还有连接,如果没有是否需要创建新的连接?这一系列问题都需要去解决,因此需要数据源LinkedlistDataSource进行优化 18。通过对连接访问加锁,来控制线程 的有序访问;通过设置初始化连接数 initCount 、最大连接数 maxCount 和当前连接数currentCount来对连接数量进行控制。 天津科技大学 2014 届 本科生 毕业论文 24 图 4-10 连接池大小控制 如上 图 4-10是连接池大小控制的 程序代码, synchronized保证了连接的分配是串行进行的,也就是先来先服务;获取连接时首先判断池中是否存在着空闲连接(也就是通过判断链表 LinkedlistSet是否为空),如果存在就从链表首部取一个连接返回;如果池中没有空闲连接,则需要判断当前连接数是否达到最大连接数,如果没有达到就可以新建一个连接,如果达到了最大连接数,就返回没有连接的信息给用户。 4.2.3、 close 方法的拦截 当然程序还存在一个比较严重的问题,那就是资源释放的方法,必须采用 free这个方法来把连接放回到链表中实现连接的复用。如果说别人应用这个 连接池但却采用的 close的方法释放,那么这个连接就会被彻底关闭,连接池也就没有达到预期的功能。为了不影响别人的习惯,让这个数据库的实现更加趋于完美,在这里就把 close方法给拦截下来,进行修改,使其达到连接放回池中的目的。 图 4-11是拦截 close方法的主要代码。 天津科技大学 2014 届 本科生 毕业论文 25 图 4-11 拦截 close 代码 创建一个新的类 ImplementConnetion实现了接口 Connetion,针对接口编程是面向对象的第一原则。 ImplementConnetion的实现需要真正的连接 Connetion和数据源 LinkedlistDataSource作为参数来把 Connetion和 LinkedlistDataSource传入,最主要的是对 close方法的修改,如果该连接当前使用次数 currentUseCount达到最大使用次数 maxUseCount,就彻底关闭;如果没有达到,就放回到链表中继续使用。 同时 LinkedlistDataSource 中的 createConnection方法也需要修改: private Connection createConnection() throws SQLException Connection Conn=DriverManager.getConnection(url, user, password); ImplementConnetion implementConnetion= new ImplementConnetion(Conn,this); return implementConnetion; 连 接 创 建 使 用 的 还 是 DriverManager 得到 Connection , 然 后 用ImplementConnetion构造得到包装后的连接,返回的连接是 ImplementConnetion,它可以应用到所有 Connection可以使用的地方,当使用 close关闭的时候还可以放回到连接池中。如下图 4-12关闭连接时用的是 close方法,同时把最大连接数天津科技大学 2014 届 本科生 毕业论文 26 maxCount设置为 、初始化连接数 initCount设置为 以及最大使用次数maxUseCount设置为,这样就可以简单地测试到最大使用次数的约束限制, 次连接就会出现前次跟后 次出现不同的连接,由于 ImplementConnetion的应用,连接也会从原来的 Connetion变为 ImplementConnetion。 图 4-12 close 拦截和最大使用次数测试 天津科技大学 2014 届 本科生 毕业论文 27 结论 (1)本文先是研究了框架的整体概念,框架应用于软件开发的特点与重要意义。然后对主要的 Java框架进行研究和简要介绍,主要包

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论