iteye_6428 2012-09-05 13:13
浏览 470
已采纳

关于java static变量初始化的疑问

java中,类的static变量作为类变量,只需要被一次初始化,就可使用,但是,我在程序中遇到一个问题:

在web.xml中配置listener,服务器启动时,ServletContextListen初始化数据源(DataSource),第一次初始化成功,但是在Test类中,调用ConnectionManager.getConnection()时,DataSource却为null,意味着ServletContextListen初始化数据源失败了,大家帮忙解答下,到底什么原因造成的,谢谢!!!

以下是代码:
[code="java"]
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();
        }

}

}

[/code]
[code="java"]
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(); } }

}

[/code]
[code="java"]
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);
    }

}

}

[/code]
[code="xml"]
<?xml version="1.0" encoding="UTF-8"?>

mysystem

index.html
index.htm
index.jsp
default.html
default.htm
default.jsp

<!-- 登录Servlet配置

LoginServlet
login.LoginServlet


LoginServlet
/login
-->


ActionDispatcher
mystruts.actionfilter.ActionDispatcher


ActionDispatcher
*.action

<!-- 数据库信息配置 -->

DataBaseConfig
c3p0/c3p0.properties


mystruts.listener.ServletContextListen


[/code]

在Test类中,调用ConnectionManager.getConnection()时,DataSource却为null,但我在debug时,跟踪查看,发现DataSource是被初始化了,不知什么原因造成初始化失败,请大家帮忙查看下,谢谢

  • 写回答

7条回答 默认 最新

  • jinnianshilongnian 2012-09-05 13:38
    关注

    没必要放到ServletContextListener。

    直接放在ConnectionManager中的static块中,默认加载classpath下的配置文件。

    如 static {
    load();

    data_source=initDB();

    return data_source;

    }
    读取classpath下的资源可以通过
    Thread.currentThread().getContextClassLoader().getResourceAsStream(name)

    public static void stop(){  
        data_source=null;   //容器销毁了 自动垃圾回收了,不需要
    } 
    

    报的什么异常,能否全部贴出来

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(6条)

报告相同问题?

悬赏问题

  • ¥50 易语言把MYSQL数据库中的数据添加至组合框
  • ¥20 求数据集和代码#有偿答复
  • ¥15 关于下拉菜单选项关联的问题
  • ¥20 java-OJ-健康体检
  • ¥15 rs485的上拉下拉,不会对a-b<-200mv有影响吗,就是接受时,对判断逻辑0有影响吗
  • ¥15 使用phpstudy在云服务器上搭建个人网站
  • ¥15 应该如何判断含间隙的曲柄摇杆机构,轴与轴承是否发生了碰撞?
  • ¥15 vue3+express部署到nginx
  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况