原创文章,转载请注明出处:http://www.aj2ee.com
又是一轮周末,10点起来,又玩电脑又玩手机的无聊的过了一上午。下午不知哪来的兴致,研究起proxool(一种Java数据库连接池技术),也是因为公司项目用到了该技术罢。
网上找些资料看过后,决定在自己的博客项目里使用。真是不用不知道,一用吓一跳,问题百出呀。先来介绍下proxool(引自百度百科)
Proxool是一种Java数据库连接池技术。是sourceforge下的一个开源项目,这个项目提供一个健壮、易用的连接池,最为关键的是这个连接池提供监控的功能,方便易用,便于发现连接泄漏的情况。目前是和DBCP以及C3P0一起,最为常见的三种JDBC连接池技术。日前,Hibernate官方宣布由于Bug太多不再支持DBCP,而推荐使用 Proxool或C3P0。
我的博客项目用的是struts2+hibernate3+spring3,之前是用spring 的 org.springframework.jdbc.datasource.DriverManagerDataSource 来创建 dataSource数据源。用spring 的org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean注解的形式管理hibernate session 现在改用proxool创建数据源。
网上的配置方法主要有2种方法:
1。同样使用org.springframework.jdbc.datasource.DriverManagerDataSource加proxool驱动来配置proxool。
在WEB-INF下创建proxool.xml或proxool.properties 配置文件:
proxool.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- the proxool configuration can be embedded within your own application's.
Anything outside the "proxool" tag is ignored. -->
<something-else-entirely>
<proxool>
<alias>DbPool</alias>
<driver-url>jdbc:mysql://localhost:3306/tblog</driver-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<driver-properties>
<properties name="user" value="root"></properties>
<properties name="password" value="123456"></properties>
<properties name="useUnicode" value="true"></properties>
<properties name="characterEncoding" value="UTF-8"></properties>
</driver-properties>
<minmum-connection-count>10</minmum-connection-count>
<maxmum-connection-count>50</maxmum-connection-count>
<maxmum-action-time>60000</maxmum-action-time>
<house-keeping-test-sql>select 1</house-keeping-test-sql>
</proxool>
</something-else-entirely>
在web.xml文件里用servlet的形式加载proxool.xml文件
web.xml
<servlet>
<servlet-name>proxoolServletConfigurator</servlet-name>
<servlet-class>
org.logicalcobwebs.proxool.configuration.ServletConfigurator
</servlet-class>
<init-param>
<param-name>xmlFile</param-name>
<param-value>WEB-INF/proxool.xml</param-value>
</init-param>
由于proxool要先加载,所以启动优先级要比spring高,否则在spring加载时会报错
<load-on-startup>1</load-on-startup>
</servlet>
在spring的applicationContext.xml里dateSource配置
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
数据源类采用JDBC数据源
<property name="driverClassName">
将数据库连接交给了proxool管理,使它的驱动
<value>org.logicalcobwebs.proxool.ProxoolDriver</value>
</property>
<property name="url">
数据库连接池的别名,与你的proxool.xml中的Alias必须一致
<value>proxool.DbPool</value>
</property>
</bean>
2.第二种方法是用hibernate-proxool.jar 加上 hibernate的一些属性配置来加载proxool.xml文件,proxool.xml文件内容同上,
applicationContext.xml里配置如下:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.connection.release_mode">
after_statement
</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
<prop key="hibernate.proxool.xml">proxool.xml</prop>
<prop key="hibernate.proxool.pool_alias">DbPool</prop>
<prop key="hibernate.proxool.existing_pool">true</prop>
<prop key="hibernate.connection.release_mode">auto</prop>
<prop key="hibernate.connection.provider_class">org.hibernate.connection.ProxoolConnectionProvider"></prop>
</props>
</property>
<property name="packagesToScan" value="org.tblog.orm"></property>
<!-- <property name="configLocation">-->
<!-- <value>classpath:hibernate.cfg.xml</value>-->
<!-- </property>-->
</bean>
注意必须加上hibernate-proxool.jar和proxool-xx.jar两个包,不然会报没有找到ProxoolConnectionProvider这个类。
第二种方法,因为电脑上没有找到hibernate-proxool.jar这个包,而有的是hibernate4.0的,而我现在用的是hibernate3,所以我没有使用该方法。
而第一种方法,配置完后,出问题了。总是报:Attempt to refer to a unregistered pool by its alias 'xxx' ,文字面意思是“ 试图引用别名为 'xxx'的连接池是未被注册的”。从网上找些资料,发现是spring、proxool 启动先后顺序的问题,绝大多数WEB容器的加载顺序是:Listener,Filter,Servlet, 我的spring是用listener来启动的,proxool是由servlet启动的,所以在spring用
org.springframework.jdbc.datasource.DriverManagerDataSource 创建dataSource的时候 ,proxool的还没有加载到proxool.xml文件,连接池还没有创建好,所以报了 连接池是未被注册 的错误。
之后我试图把spring用servlet的形式启动,
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>-->
用 <load-on-startup>2</load-on-startup> 来设置servlet的启动顺序。proxool servlet 设置<load-on-startup> 1</load-on-startup>。
改后启动tomcat服务,struts2报错了。我配置的struts2的action类是交由spring管理的:
<!-- 设置Struts2默认的ObjectFactory为spring -->
<constant name="struts.objectFactory" value="spring" />
struts2与spring进行整合时,web.xml中的spring加载必须使listener来加载,如果使用ContextLoderServlet,则会出空指向异常,报的是Struts2的objectFactory中的某处。
我把struts2的<constant name= "struts.objectFactory" value= "spring" /> 注释掉,action类不让spring来管理。重启tomcat服务后,竟然报ContextLoderServlet没有找到,我郁闷了,不知道网上那些写博客的真是用心写了吗? 也不说明下是spring2的,我在我项目的spring3相关的jar包下,的确没有找到ContextLoderServlet,或许spring3就不支持servlet启动吧。
折腾的半天还是没有解决,好了,不管了,用第三种方法,也是我现在使用的,不用proxool.xml文件
只需配置applicationContext.xml文件即可
<!-- 加載 properties 配置文件 -->
<bean id="propertyConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<!-- Proxool 配置一 -->
<bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">
<property name="alias" value="${proxool.alias}"></property>
<property name="driver" value="${driverClassName}"></property>
<property name="driverUrl" value="${mysqlurl}"></property>
<property name="user" value="${username}"></property>
<property name="password" value="${password}"></property>
<property name="maximumConnectionCount" value="${proxool.maximumConnectionCount}"></property>
<property name="minimumConnectionCount" value="${proxool.minimumConnectionCount}"></property>
<property name="maximumActiveTime" value="${proxool.maximumActiveTime}"></property>
<property name="prototypeCount" value="${proxool.prototypeCount}"></property>
<property name="houseKeepingTestSql" value="${proxool.houseKeepingTestSql}"></property>
</bean>
jdbc.properties
hostip=localhost
mysqlport=3306
encoding=UTF-8
driverClassName=com.mysql.jdbc.Driver
mysqlurl=jdbc:mysql://localhost:3306/tblog?useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
proxool.alias=DbPool
proxool.maximumConnectionCount=50
proxool.minimumConnectionCount=10
proxool.maximumActiveTime=60000
proxool.prototypeCount=5
proxool.houseKeepingTestSql=select 1
下面是一些相关博文地址:
http://www.iteye.com/topic/252675#696545
http://blog.youkuaiyun.com/zoutuo/article/details/6301319
http://wt8414.iteye.com/blog/242628
http://baike.baidu.com/view/2098784.htm
proxool的 数据库连接监控器 配置
web.xml
<!-- 数据库连接监控器 -->
<servlet>
<servlet-name>proxoolAdmin</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>proxoolAdmin</servlet-name>
<url-pattern>/proxoolAdmin</url-pattern>
</servlet-mapping>
<!-- 配置受保护域,只有Tomcat管理员才能察看连接池的信息-->
<security-constraint>
<web-resource-collection>
<web-resource-name>proxoolAdmin</web-resource-name>
<url-pattern>/proxoolAdmin</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>proxool manager Application</realm-name>
</login-config>
<security-role>
<description>The role that is required to log in to the Manager Application</description>
<role-name>manager</role-name>
</security-role>