Spring+Hibernate与proxool连接池的配置

本文详细介绍了如何在Spring+Hibernate项目中配置Proxool连接池,以连接MySQL数据库。步骤包括下载proxool库,创建ProxoolConf.xml配置文件,修改web.xml和applicationContext.xml。在weblogic服务器上部署时,可能遇到找不到配置文件的问题,解决方案是通过自定义listener加载配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前一篇文章讲过了如何在Hibernate中配置Proxool以连接oracle 11g,今天这篇来讲针对Spring+Hibernate如何对proxool连接池进行配置。

这次以MySQL为例。

第一步:首先去http://proxool.sourceforge.net/下载proxool.zip文,现在最新版本是proxool-0.9.1,解压缩后从中找到proxool-0.9.1.jar和proxool-cglib.jar,导入到对应的web项目中。如果用的是proxool-0.8.3,那只需导入一个jar包——proxool-0.8.3.jar。

第二步:就是写一个单独的ProxoolConf.xml文件放到WEB-INF文件夹下。这次用的数据库是MySQL. 

ProxoolConf.xml的配置文件如下: 

<?xml version="1.0" encoding="UTF-8"?>
<something-else-entirely>
<proxool>
<alias>ConnectionPool</alias>
<driver-url>jdbc:mysql://localhost:3306/myTest</driver-url> 
<driver-class>com.mysql.jdbc.Driver</driver-class>
<driver-properties>
<property name="user" value="ukpss"/>
<property name="password" value="ukpss"/>
</driver-properties>

<house-keeping-sleep-time>90000</house-keeping-sleep-time>
<maximum-new-connections>20</maximum-new-connections>
<prototype-count>5</prototype-count>
<maximum-connection-count>100</maximum-connection-count>
<minimum-connection-count>10</minimum-connection-count>
<maximum-active-time>900000</maximum-active-time> 
<maximum-connection-lifetime>1200000</maximum-connection-lifetime> 
</proxool>
</something-else-entirely>
具体的元素说明请参看我的另一篇文章,Hibernate配置Proxool以连接oracle 11g

第三步:加载并初始化proxool.xml文件。

因为它是连接数据库的,其他很多模块都用到数据,所以你必须首先加载它,在web.xml中进行如下配置:

<servlet> 
	    <servlet-name>ServletConfigurator</servlet-name> 
	    <servlet-class> 
	    org.logicalcobwebs.proxool.configuration.ServletConfigurator 
	    </servlet-class> 
	    <init-param> 
		    <param-name>xmlFile</param-name> 
		    <param-value>WEB-INF/ProxoolConf.xml</param-value> 
	    </init-param> 
	    <load-on-startup>1</load-on-startup> 
</servlet>

如果你以前加载applicationContext.xml用的是

<listener> 
    <listener-class> 
    org.springframework.web.context.ContextLoaderListener 
    </listener-class> 
</listener> 

由于listener先于servlet被加载,必须改为

<servlet> 
    <servlet-name>contextConfigLocation</servlet-name> 
    <servlet-class> 
    org.springframework.web.context.ContextLoaderServlet 
    </servlet-class> 
    <load-on-startup>2</load-on-startup> 
</servlet>
【如果报找不到org.springframework.web.context.ContextLoaderServlet的错误,则到网上下载一个spring-web.jar放入工程项目即可。】

要不然你就会遇见这样的错误: 
Problem 

    

org.logicalcobwebs.proxool.ProxoolException: Attempt to refer to a unregistered pool by its alias ‘ConnectionPool’
 如果用过proxool与spring整合时,不少就遇到过这样的问题,其实这个问题很明显就是你的proxool.xml没有被先加载初始化,我们应该让它先加载。

完整的web.xml的配置内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	
	<!-- servlet for proxool -->
  	<servlet> 
	    <servlet-name>ServletConfigurator</servlet-name> 
	    <servlet-class> 
	    org.logicalcobwebs.proxool.configuration.ServletConfigurator 
	    </servlet-class> 
	    <init-param> 
		    <param-name>xmlFile</param-name> 
		    <param-value>WEB-INF/ProxoolConf.xml</param-value> 
	    </init-param> 
	    <load-on-startup>1</load-on-startup> 
    </servlet>
	<!-- servlet for proxool -->
    
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
		classpath*:/com/config/spring/applicationContext-resource.xml,
		classpath*:/com/config/spring/applicationContext-mapping.xml,
		classpath*:/com/config/spring/applicationContext-adminAction.xml,
		
		</param-value>
	</context-param>
	<servlet> 
	    <servlet-name>contextConfigLocationServlet</servlet-name> 
	    <servlet-class> 
	    org.springframework.web.context.ContextLoaderServlet 
	    </servlet-class> 
	    <load-on-startup>2</load-on-startup> 
    </servlet> 
  
   <!-- load authority info into servlet context -->
  
   
   <!-- load category data cache in servletcontext when spring application context creation complete -->
  
   
   <!-- Introspector 缓存清除监听器 -->
   <listener>
    <listener-class>
   	 org.springframework.web.util.IntrospectorCleanupListener
    </listener-class>
   </listener>
   
   <!-- encodingFilter to encode every page with GB2312 -->
	<filter>
	    <filter-name>encodingFilter</filter-name>
	    <filter-class>
	        org.springframework.web.filter.CharacterEncodingFilter
	    </filter-class>
	    <init-param>
	        <param-name>encoding</param-name>
	        <param-value>utf-8</param-value>
	    </init-param>
	    <init-param>
	        <param-name>forceEncoding</param-name>
	        <param-value>true</param-value>
	    </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

   <!-- security Filter -->
	<servlet>
		<servlet-name>Dispatcher</servlet-name>
		<servlet-class>
			org.springframework.web.servlet.DispatcherServlet
		</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>
			
			</param-value>
		</init-param>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>Dispatcher</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
		
  <filter>
     <filter-name>OpenSessionInViewFilter</filter-name>
      <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
       <init-param> 
           <param-name>flushMode</param-name> 
           <param-value>AUTO</param-value> 
       </init-param>
</filter>
<filter-mapping>
     <filter-name>OpenSessionInViewFilter</filter-name>
     <url-pattern>/*</url-pattern>
</filter-mapping>
	
  <welcome-file-list>
    <welcome-file>consumer/consumerLogin.jsp</welcome-file>
  </welcome-file-list>
   
</web-app>
最后一步:整合spring和proxool。

在applicationContext.xml文件中把原来数据源的配置成这样: 

<?xml version="1.0" encoding="UTF-8"?>     
<beans xmlns="http://www.springframework.org/schema/beans"     
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">     
    <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.ConnectionPool</value>  <!--注意,此处的proxool并不是ProxoolConf.xml的文件名,不管你取什么文件名,这边都是用proxool. -->
        </property>     
    </bean>     
    <bean id="sessionFactory"     
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">     
        <property name="dataSource">     
            <ref bean="dataSource" />     
        </property>     
        <property name="hibernateProperties">     
            <props>     
                <prop key="hibernate.dialect">     
                     org.hibernate.dialect.MySQLDialect      
                </prop>     
                <prop key="hibernate.connection.autocommit">true</prop>     
                <prop key="hibernate.show_sql">true</prop>     
                                    <!--   
此处要注意因为proxool自己释放数据库连接比慢,所以要在此给出释放连接的模式,具体几种模式对应的意思,可以Google一下hibernate.connection.release_mode,有很多说明,在此不多说  
-->     
                <prop key="hibernate.connection.release_mode">     
                     after_statement      
                </prop>     
            </props>     
        </property>     
        <property name="mappingResources">     
            <list>     
                <value>cn/wt/vo/Admin.hbm.xml</value>     
                <value>cn/wt/vo/User.hbm.xml</value>      
            </list>     
        </property>     
    </bean>     
    <bean id="hibernateTemplate"     
        class="org.springframework.orm.hibernate3.HibernateTemplate">     
        <property name="sessionFactory">     
            <ref bean="sessionFactory" />     
        </property>     
    </bean>     
    <bean id="adminDao" class="cn.wt.dao.AdminDao" abstract="true" />     
    <bean id="adminDaoImpl" class="cn.wt.dao.impl.AdminDaoImpl"     
        parent="adminDao">     
        <property name="hibernateTemplate">     
            <ref bean="hibernateTemplate" />     
        </property>     
    </bean>
</beans>

这个 <property name="url">要配置成proxool.xml中的别名。其他地方不用改了。
如果会报无法为proxool.ConnectionPool加载驱动org.logicalcobwebs.proxool.ProxoolDriver,则应考虑是否ProxoolConf.xml的编码(如UTF-8)有问题。
至此配置就结束了!

如果你用的服务器是weblogic,那么恭喜你,在tomcat下运行好好的项目,到weblogic上可能会出现各种问题,两种web容器区别还是比较大的。这里,我仅介绍一下关于proxool会出现的问题:

按上面的配置,在tomcat上能无差错地运行,但在weblogic下会出现找不到ProxoolConf.xml文件的问题(特别是你以war包进行部署的时候),这是因为tomcat与weblogic默认的根目录不同。

这里,我们就不再使用servlet,改用listener来实现,这时就需要自己写一个listener类来加载proxool的配置文件,完整代码如下:

package com.airconditioner.proxool.listener;

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.log4j.Logger;
import org.logicalcobwebs.proxool.ProxoolException;
import org.logicalcobwebs.proxool.configuration.JAXPConfigurator;
import org.logicalcobwebs.proxool.configuration.PropertyConfigurator;

public class ProxoolListener implements ServletContextListener {
	private static final Logger logger = Logger
			.getLogger(ProxoolListener.class);
	private static final String XML_FILE_PROPERTY = "xmlFile";
	private static final String PROPERTY_FILE_PROPERTY = "propertyFile";
	private static final String AUTO_SHUTDOWN_PROPERTY = "autoShutdown";
	private boolean autoShutdown = true;

	public void contextDestroyed(ServletContextEvent arg0) {
		System.out.println("destroy database pool....");
	}

	public void contextInitialized(ServletContextEvent contextEvent) {
		System.out.println(">>>>>>ProxoolListener init");
		ServletContext context = contextEvent.getServletContext(); // 对应servlet的init方法中ServletConfig.getServletContext()
		String appDir = this.getClass().getClassLoader().getResource("/").getPath();
		logger.info(">>>>>>appDir: "+appDir);
		//contextEvent.getServletContext().getResourceAsStream("");
		Properties properties = new Properties();
		Enumeration<?> names = context.getInitParameterNames();
		while (names.hasMoreElements()) {
			String name = (String) names.nextElement();
			String value = context.getInitParameter(name);
			String pathString = "";
			if (name.equals(XML_FILE_PROPERTY)) {
				
				try {
					File file = new File(value);
					if (file.isAbsolute()) {
						JAXPConfigurator.configure(value, false);
					} else {
						pathString=appDir + ".." + File.separator + value;//
						JAXPConfigurator.configure(pathString, false);
					}
				} catch (ProxoolException e) {
					logger.error("Problem configuring pathString: " + pathString, e);
				}
			} else if (name.equals(PROPERTY_FILE_PROPERTY)) {
				try {
					File file = new File(value);
					if (file.isAbsolute()) {
						PropertyConfigurator.configure(value);
					} else {
						pathString=appDir + ".." + File.separator + value;//appDir + 
						PropertyConfigurator.configure(pathString);
					}
				} catch (ProxoolException e) {
					logger.error("Problem configuring pathString2: " + pathString, e);
				}
			} else if (name.equals(AUTO_SHUTDOWN_PROPERTY)) {
				autoShutdown = Boolean.valueOf(value).booleanValue();
			} else if (name.startsWith("jdbc")) {

				properties.setProperty(name, value);
			}
		}
		if (properties.size() > 0) {
			try {
				PropertyConfigurator.configure(properties);
			} catch (ProxoolException e) {
				logger.error("Problem configuring using init properties", e);
			}
		}

	}
}
其中,String appDir = this.getClass().getClassLoader().getResource("/").getPath();是用来获得weblogic下该项目的根目录,
得到的结果类似于XXX/XXXX项目/agmkr0/war/WEB-INF/classes/,由于 ProxoolConf.xml我们放在了WEB-INF下,因此只要回退一层目录即可(用../)。用listener后,就不用多加载spring-web.jar包了。其他配置不变,修改web.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
		classpath*:/com/config/spring/applicationContext-resource.xml,
		classpath*:/com/config/spring/applicationContext-mapping.xml,
		classpath*:/com/config/spring/applicationContext-adminAction.xml,
		
		</param-value>
	</context-param>
	
	<!--proxool  -->
    <context-param>
		  <param-name>xmlFile</param-name>
		  <param-value>ProxoolConf.xml</param-value>
 	</context-param>
 	
	<listener>
  	<!-- 一定要排在所有listener前面 -->
       <listener-class>com.airconditioner.proxool.listener.ProxoolListener</listener-class>
    </listener>
    
	<listener> 
    <listener-class> 
    org.springframework.web.context.ContextLoaderListener 
    </listener-class> 
    </listener>
  
   <!-- load authority info into servlet context -->
  
   
   <!-- load category data cache in servletcontext when spring application context creation complete -->
  
   
   <!-- Introspector 缓存清除监听器 -->
   <listener>
    <listener-class>
   	 org.springframework.web.util.IntrospectorCleanupListener
    </listener-class>
   </listener>
   
   <!-- encodingFilter to encode every page with GB2312 -->
	<filter>
	    <filter-name>encodingFilter</filter-name>
	    <filter-class>
	        org.springframework.web.filter.CharacterEncodingFilter
	    </filter-class>
	    <init-param>
	        <param-name>encoding</param-name>
	        <param-value>utf-8</param-value>
	    </init-param>
	    <init-param>
	        <param-name>forceEncoding</param-name>
	        <param-value>true</param-value>
	    </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

   <!-- security Filter -->
	<servlet>
		<servlet-name>Dispatcher</servlet-name>
		<servlet-class>
			org.springframework.web.servlet.DispatcherServlet
		</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>
			
			</param-value>
		</init-param>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>Dispatcher</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
	
	
  <filter>
     <filter-name>OpenSessionInViewFilter</filter-name>
      <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
       <init-param> 
           <param-name>flushMode</param-name> 
           <param-value>AUTO</param-value> 
       </init-param>
</filter>
<filter-mapping>
     <filter-name>OpenSessionInViewFilter</filter-name>
     <url-pattern>/*</url-pattern>
</filter-mapping>

  

	
  <welcome-file-list>
    <welcome-file>consumer/consumerLogin.jsp</welcome-file>
  </welcome-file-list>
   
</web-app>
其中修改、增加的部分如下:

<!--proxool  -->
    <context-param>
	<param-name>xmlFile</param-name>
	<param-value>ProxoolConf.xml</param-value>
    </context-param>
 	
    <listener>
  	<!-- 一定要排在所有listener前面 -->
       <listener-class>com.airconditioner.proxool.listener.ProxoolListener</listener-class>
    </listener>
由于listener得到的路径已经包含了WEB-INF,所以xmlFile对应的路径就不在写上这个了。
这样修改完,就可以同时 支持weblogic和tomcat啦!

参考文章:
项目中成功的运用proxool连接池
Spring整合Hibernate时使用proxool连接池













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值