Spring+Hibernate与proxool连接池的配置

来源:互联网 发布:淘宝vintage首饰 编辑:程序博客网 时间:2024/05/22 13:00

前一篇文章讲过了如何在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连接池













0 0
原创粉丝点击