java中,类的static变量作为类变量,只需要被一次初始化,就可使用,但是,我在程序中遇到一个问题:
在web.xml中配置listener,服务器启动时,ServletContextListen初始化数据源(DataSource),第一次初始化成功,但是在Test类中,调用ConnectionManager.getConnection()时,DataSource却为null,意味着ServletContextListen初始化数据源失败了,大家帮忙解答下,到底什么原因造成的,谢谢!!!
以下是代码:
package c3p0.connection;
import java.beans.PropertyVetoException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class ConnectionManager {
private static DataSource data_source=null;;
private static Properties props=null;
private static String porps_name=null;
/**
* 创建数据库连接池
* @return
*/
private static DataSource createDataSource(){
load();
data_source=initDB();
return data_source;
}
/**
* 加载配置文件
*/
private static void load(){
try {
props = new Properties();
InputStream in=Thread.currentThread().getContextClassLoader().getResourceAsStream(porps_name);
props.load(in);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 初始化数据库
*/
private static DataSource initDB(){
System.out.println("开始初始化数据源...");
ComboPooledDataSource pool_ds=new ComboPooledDataSource();
try {
pool_ds.setDriverClass(getProperty("c3p0.connection.driverClass"));
} catch (PropertyVetoException e) {
e.printStackTrace();
throw new RuntimeException("数据库驱动加载失败");
}
pool_ds.setJdbcUrl(getProperty("c3p0.connection.url"));
pool_ds.setUser(getProperty("c3p0.connection.user"));
pool_ds.setPassword(getProperty("c3p0.connection.password"));
pool_ds.setInitialPoolSize(Integer.parseInt(getProperty("c3p0.connection.initialPoolSize")));
pool_ds.setMaxPoolSize(Integer.parseInt(getProperty("c3p0.connection.maxPoolSize")));
pool_ds.setMinPoolSize(Integer.parseInt(getProperty("c3p0.connection.minPoolSize")));
pool_ds.setMaxIdleTime(Integer.parseInt(getProperty("c3p0.connection.maxIdleTime")));
pool_ds.setAcquireIncrement(Integer.parseInt(getProperty("c3p0.connection.acquireIncrement")));
pool_ds.setAcquireRetryAttempts(Integer.parseInt(getProperty("c3p0.connection.acquireRetryAttempts")));
pool_ds.setAcquireRetryDelay(Integer.parseInt(getProperty("c3p0.connection.acquireRetryDelay")));
pool_ds.setTestConnectionOnCheckout(Boolean.parseBoolean(getProperty("c3p0.connection.testConnectionOnCheckout")));
pool_ds.setTestConnectionOnCheckin(Boolean.parseBoolean(getProperty("c3p0.connection.testConnectionOnCheckin")));
pool_ds.setIdleConnectionTestPeriod(Integer.parseInt(getProperty("c3p0.connection.idleConnectionTestPeriod")));
pool_ds.setCheckoutTimeout(Integer.parseInt(getProperty("c3p0.connection.checkoutTimeout")));
pool_ds.setAutomaticTestTable(getProperty("c3p0.connection.automaticTestTable"));
System.out.println("数据源初始化完毕...");
return pool_ds;
}
/**
* 获取c3p0连接池文件配置信息
* @param key
* @return
*/
private static String getProperty(String key){
if(key==null||"".equals(key)){
throw new NullPointerException("key不能为空!!!请检查key的赋值!!!");
}
return props.getProperty(key);
}
public static Connection getConnection() throws SQLException{
data_source=(data_source==null) ? createDataSource() : data_source;
return data_source.getConnection();
}
public static void start(String porps_name) throws SQLException{
ConnectionManager.porps_name=porps_name;
Connection conn=getConnection();
conn.close();
}
public static void stop(){
data_source=null;
}
public static void release(Connection conn,PreparedStatement pstmt,ResultSet res){
try {
if(conn!=null){
conn.close();
}
if(pstmt!=null){
pstmt.close();
}
if(res!=null){
res.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package mystruts.listener;
import java.sql.SQLException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import c3p0.connection.ConnectionManager;
/**
* ServletContext 上下文监听器
* 应用服务器一启动就产生该对象,服务器关闭即销毁
* 作用于全局,所有Servlet ,相当于静态变量
* @author tianly
*
*/
public class ServletContextListen implements ServletContextListener {
/**
* web服务器关闭时执行
*/
@Override
public void contextDestroyed(ServletContextEvent event) {
/**
* 关闭数据源
*/
ConnectionManager.stop();
}
/**
* web服务器启动时执行
*/
@Override
public void contextInitialized(ServletContextEvent event) {
/**
* 初始化数据源
*/
String db_url=event.getServletContext().getInitParameter("DataBaseConfig");
try {
ConnectionManager.start(db_url);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package test.c3p0;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import c3p0.connection.ConnectionManager;
import c3p0.util.DateUtil;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
String currdate=DateUtil.getDateTime();
Connection conn=null;
PreparedStatement pstmt=null;
ResultSet res=null;
try {
String sql="insert into userinfo(username,password,sex,regdate) values(?,?,?,?)";
String sql4ID="select LAST_INSERT_ID()";
conn=ConnectionManager.getConnection();
conn.setAutoCommit(false);
pstmt=conn.prepareStatement(sql);
pstmt.setString(1, "tly");
pstmt.setString(2, "tly");
pstmt.setInt(3, 0);
pstmt.setString(4, currdate);//mysql中无需进行日期格式转换
pstmt.executeUpdate();
pstmt=conn.prepareStatement(sql4ID);
res=pstmt.executeQuery();
if(res.next()){
int ID=res.getInt(1);
System.out.println("ID:"+ID);
}
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
ConnectionManager.release(conn, pstmt, res);
}
}
}
mysystem
index.html
index.htm
index.jsp
default.html
default.htm
default.jsp
ActionDispatcher
mystruts.actionfilter.ActionDispatcher
ActionDispatcher
*.action
DataBaseConfig
c3p0/c3p0.properties
mystruts.listener.ServletContextListen
在Test类中,调用ConnectionManager.getConnection()时,DataSource却为null,但我在debug时,跟踪查看,发现DataSource是被初始化了,不知什么原因造成初始化失败,请大家帮忙查看下,谢谢