文档内容可以通过以下URL 下载:
http://download.csdn.net/detail/attagain/5535283
B/S结构应用系统的建设,必然会遇到SSH的整合问题。使用PROXOOL配置数据库连接池时,
相信都会为连接池Servlet和Spring的启动顺序而烦恼。
首先,需要说明一下SSH架构,以及各个部分的分工。SSH架构是符合MVC模型的:Struts2,
承担着控制器(Controller)的角色;Spring,则承担着数据模型(Model)的角色,主要处理
业务逻辑工作;Hibernate,则承担着数据模型的延伸,持久层的数据处理角色。明白这些关系,
接下来也就方便说明,SSH之间的逻辑处理关系,从而方便理清依赖关系。
Struts2和Spring的整合,借助于struts2-spring-plugin-*.jar工具,要求Spring必须
以listener的方式加载;proxool方式配置数据库连接池,比较常用的方式是,使用Servlet方式
启动;Web服务启动依赖于Web.xml,按照类型加载启动顺序是,context-param、listener、
filter、servlet;Spring依赖于数据库连接池,因此,数据库连接池需要先于Spring启动。
如果,数据库连接池采用传统的Servlet方式,Spring采用listener方式,则必然存在启
动加载顺序的异常信息。事实证明,确实如此,Web服务启动时,报出如下异常信息:
java.sql.SQLException: org.logicalcobwebs.proxool.ProxoolException: Attempt to
refer to a unregistered pool by its alias ‘Develop’。
从根本上解决此问题的方法是,让数据库连接池优先于Spring启动。Spring必须以listener
方式启动,Web服务启动的最优顺序也是listener方式。因此,我们的数据库也必须以listener
方式启动,并且要放在Spring之前。
目前使用的proxool-0.9.1.jar,还没有现成的listener类,所以,我们必须建立自己的
proxool监听类。为了实现该功能,本人参考了proxool源程序
org.logicalcobwebs.proxool.configuration.ServletConfigurator,经过简单改造,最终
实现所要求功能。由于,线程池管理工具,只是普通的Servlet程序,一次也没有改装成listener
的必要。基于此,接下来是本人围绕proxool,整合SSH的具体步骤。
1、proxool官网,下载最新的proxool-0.9.1.jar
官网下载URL:
jar包下载
http://sourceforge.net/projects/proxool/files/proxool/0.9.1/proxool-0.9.1.zip/download
源码下载
http://sourceforge.net/projects/proxool/files/proxool/0.9.1/proxool-0.9.1-source.zip/download
2、创建独立的proxool.xml文件,同时存在Web的WEB-INF目录下,根据自己的数据库类型,
填写不同的数据库驱动信息及具体配置信息,本文以oracle为例。
<?xml version="1.0" encoding="utf-8"?>
<something-else-entirely>
<!-- 开发环境配置 -->
<proxool>
<!-- 数据源别名 -->
<alias>Develop</alias>
<!-- 数据库驱动 -->
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<!-- 数据库连接URL -->
<driver-url>
<!-- 开发环境配置 -->
jdbc:oracle:thin:@127.0.0.1:1521:orcl
</driver-url>
<!-- 用户验证权限 -->
<driver-properties>
<!-- 用户名 -->
<property name="user" value="数据库用户名" />
<!-- 密码 -->
<property name="password" value="数据库登录密码" />
</driver-properties>
<!-- 最小连接数(默认2个) -->
<minimum-connection-count>20</minimum-connection-count>
<!-- 最大连接数(默认5个),超过了这个连接数,再有请求时,就排在队列中等候 -->
<maximum-connection-count>150</maximum-connection-count>
<!-- 一个连接的最长活动时间4小时,单位毫秒 -->
<maximum-connection-lifetime>14400000</maximum-connection-lifetime>
<!--自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁 默认30秒-->
<house-keeping-sleep-time>90000</house-keeping-sleep-time>
<!--最少保持的空闲连接数(默认2个)-->
<prototype-count>5</prototype-count>
<!--在使用之前测试-->
<test-before-use>true</test-before-use>
<!-- 用于保持连接的测试语句 -->
<house-keeping-test-sql>
SELECT 1 FROM DUAL
</house-keeping-test-sql>
<!-- 如果为true,那么每个被执行的SQL语句将会在执行期被log记录(DEBUG LEVEL) -->
<trace>true</trace>
<verbose>true</verbose>
</proxool>
</something-else-entirely>
3、创建自定义数据库连接池监听
package com.jlinfo.framework;
import java.io.File;
import java.util.Enumeration;
import java.util.Properties;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.logicalcobwebs.proxool.ProxoolException;
import org.logicalcobwebs.proxool.ProxoolFacade;
import org.logicalcobwebs.proxool.configuration.JAXPConfigurator;
import org.logicalcobwebs.proxool.configuration.PropertyConfigurator;
/**
* <b>Function Name:</b>系统框架_数据库连接池监听器。<br>
* <b>History:</b>2013/05/10 attagain create<br>
* <br>
*
* @author attagain
* @version 1.0.0 2013/05/10
*/
public class DbPoolProxoolListener implements ServletContextListener {
/**
* LOG输出对象
*/
private static final Log LOG = LogFactory
.getLog(DbPoolProxoolListener.class);
/**
* 上下文参数_xmlFile(XML文件)
*/
private static final String CONTEXT_PARAM_XMLFILE = "xmlFile";
/**
* 上下文参数_propertyFile(属性配置文件)
*/
private static final String CONTEXT_PARAM_PROPERTYFILE = "propertyFile";
/**
* 上下文参数_autoShutdown(自动关闭)
*/
private static final String AUTO_SHUTDOWN_PROPERTY = "autoShutdown";
/**
* 数据库属性前缀
*/
private static final String PREFIX_JDBC = "jdbc";
/**
* Servlet上下路径_根
*/
private static final String SERVLET_PATH_ROOT = "/";
/**
* 自动退出
*/
private boolean autoShutdown = true;
/**
* 数据库连接池监听初始化。<br>
*
* @param servletContextEvent
* servlet上下文事件参数对象
*/
public void contextInitialized(ServletContextEvent servletContextEvent) {
// 获取Servlet上下文对象
ServletContext context = servletContextEvent.getServletContext();
// 获取Servlet上下文根的绝对路径
String appDir = servletContextEvent.getServletContext().getRealPath(
SERVLET_PATH_ROOT);
// 定义属性配置信息对象
Properties properties = new Properties();
// 获取上下文初始化参数集合
Enumeration<?> names = context.getInitParameterNames();
// 逐个循环处理上下文参数信息
while (names.hasMoreElements()) {
// 获取参数名
String name = names.nextElement().toString();
// 根据参数名,获取参数值
String value = context.getInitParameter(name);
if (CONTEXT_PARAM_XMLFILE.equals(name)) {
// XML配置的情况
try {
// 获取配置文件句柄
File file = new File(value);
if (file.isAbsolute()) {
// 相对路径
JAXPConfigurator.configure(value, false);
} else {
// 绝对路径
JAXPConfigurator.configure(appDir + File.separator
+ value, false);
}
} catch (ProxoolException e) {
LOG.error("Problem configuring " + value, e);
}
} else if (CONTEXT_PARAM_PROPERTYFILE.equals(name)) {
// 属性文件配置的情况
try {
// 获取配置文件句柄
File file = new File(value);
if (file.isAbsolute()) {
// 相对路径
PropertyConfigurator.configure(value);
} else {
// 绝对路径
PropertyConfigurator.configure(appDir + File.separator
+ value);
}
} catch (ProxoolException e) {
LOG.error("Problem configuring " + value, e);
}
} else if (AUTO_SHUTDOWN_PROPERTY.equals(name)) {
// 自动关闭的情况
autoShutdown = Boolean.valueOf(value).booleanValue();
} else if (PREFIX_JDBC.startsWith(name)) {
// 其他情况(JDBC开头的字符)
properties.setProperty(name, value);
}
}
if (properties.size() > 0) {
// 自定义属性存在的情况
try {
// 配置自定属性
PropertyConfigurator.configure(properties);
} catch (ProxoolException e) {
LOG.error("Problem configuring using init properties", e);
}
}
}
/**
* 数据库连接池监听销毁。<br>
*
* @param servletContextEvent
* servlet上下文事件参数对象
*/
public void contextDestroyed(ServletContextEvent servletContextEvent) {
if (this.autoShutdown) {
ProxoolFacade.shutdown(0);
}
}
}
4、整合Struts2、Spring和proxool,配置Web服务启动配置文件[web.xml]
4.1、开始的位置,配置数据库连接池监听,确保第一时间启动;接着配置数据库连接池管理Servlet。
<!-- 对PROXOOL进行配置 -->
<!-- 线程池监听启动参数 -->
<context-param>
<param-name>xmlFile</param-name>
<param-value>WEB-INF/proxool.xml</param-value>
</context-param>
<!-- 线程池监听 -->
<listener>
<listener-class>com.jlinfo.framework.DbPoolProxoolListener</listener-class>
</listener>
<!-- 线程池管理Servlet -->
<servlet>
<servlet-name>AdminP</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AdminP</servlet-name>
<url-pattern>/AdminP</url-pattern>
</servlet-mapping>
4.2、接下来配置Spring监听
<!-- 对spring进行配置 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
5、整合Spring和proxool,配置应用上下文配置文件[applicationContext.xml]
5.1、配置数据源bean
<!-- 数据库配置 -->
<!-- PROXOOL 设置 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.logicalcobwebs.proxool.ProxoolDriver" />
<property name="url" value="proxool.Develop" />
</bean>
<!-- 持久层配置 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource"
ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
<property name="mappingResources">
<list>
<!-- 数据库表映射,每一个Value配置代表一个表的映射关系 -->
<value>com/wids/department/bean/DepBean.hbm.xml</value>
<value>com/wids/userinfo/bean/UserInfoBean.hbm.xml</value>
<value>com/wids/syslog/bean/SysLogBean.hbm.xml</value>
<value>com/wids/treemenu/bean/TreeMenuBean.hbm.xml</value>
<value>com/wids/integral/bean/IntegralBean.hbm.xml</value>
<value>com/wids/integralgroups/bean/IntegralGroupsBean.hbm.xml</value>
<value>com/wids/news/bean/NewsBean.hbm.xml</value>
<value>com/wids/news/bean/NewsLogBean.hbm.xml</value>
<value>com/wids/count/bean/StatisticBean.hbm.xml</value>
<value>com/wids/count/bean/TempStatisticBean.hbm.xml</value>
<value>com/wids/count/bean/TempAllStatisticBean.hbm.xml</value>
<value>com/wids/sms/bean/SmsBean.hbm.xml</value>
<value>com/wids/fjintegral/bean/FjiBean.hbm.xml</value>
<value>com/wids/count/bean/TempStatisticUserBean.hbm.xml</value>
<value>com/wids/filezn/bean/FileznBean.hbm.xml</value>
<!-- [优秀专题]、[优秀信息]板块 add attagain 2013/05/10 S -->
<value>com/wids/news/bean/NewsExcBean.hbm.xml</value>
<value>com/wids/news/bean/NewsCommentBean.hbm.xml</value>
<!-- [优秀专题]、[优秀信息]板块 add attagain 2013/05/10 E -->
<!-- 数据库表映射结束 -->
</list>
</property>
</bean>
<!-- 配置事务 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
至此,是一个完整的,可正常运行的SSH+PROXOOL的配置。需要说明的的是,如果需要通过Web
访问数据库连接池管理Servlet,URL(注意区分大小写): http://127.0.0.1:8080/[网站Root]/AdminP
文档内容可以通过以下URL 下载:
http://download.csdn.net/detail/attagain/5535283