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");
即可