java的数据库连接池很大的提高了效率,但是同时也引入了另一个效率问题, 那就是每次建立连接前都要进行jndi查询以获取数据源,而jndi查询的效率也是比较低的。
解决的方法就是利用ServletContext实现一个全局变量的概念,在每次服务器启动的时候,声明一个数据源,查询jndi获取数据源实例,然后将实例放到ServletContext,以后使用直接取出即可。
具体实现:编写一个类,实现ServletContextListener,在contextInitialized方法中得到数据源实例,放入ServletContext。然后将这个ServletContextListener注册到web.xml。
package pub; //my own class
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.naming.*;
import javax.sql.DataSource;
import javax.servlet.http.HttpServlet;
public class MyListener extends HttpServlet implements ServletContextListener
{
private ServletContext context = null;
public void contextInitialized(ServletContextEvent event)
{
context = event.getServletContext();
DataSource ds = null;
Context ctx=null;
try
{
ctx=new InitialContext();
ds=(javax.sql.DataSource)ctx.lookup("java:comp/env/jdbc/mypool");
}
catch(NamingException ne)
{
ne.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
context.setAttribute("ds", ds);
}
public void contextDestroyed(ServletContextEvent event)
{
context.removeAttribute("ds");
}
}
注册:
在web.xml中,连接池配置行之后加入
<listener>
<listener-class>pub.MyListener</listener-class>
</listener>
这样每次服务启动时就会自动执行contextInitialized方法,以后需要ds时,
DataSource ds = (DataSource)this.getServletContext().getAttribute("ds");
即可