Java servlet中的JNDI查找';s init参数是个好主意吗?
我目前正在构建一个JavaEEWeb应用程序,并找到了一篇文章,它为我提供了一些关于如何构建更好的应用程序的很好的指导。第一个技巧是“使用HttpServlet init()方法缓存数据”。这听起来像一个天才的想法,但现在我已经实现了自己的版本,我担心线程安全和保持连接打开Java servlet中的JNDI查找';s init参数是个好主意吗?,java,performance,jakarta-ee,jdbc,jndi,Java,Performance,Jakarta Ee,Jdbc,Jndi,我目前正在构建一个JavaEEWeb应用程序,并找到了一篇文章,它为我提供了一些关于如何构建更好的应用程序的很好的指导。第一个技巧是“使用HttpServlet init()方法缓存数据”。这听起来像一个天才的想法,但现在我已经实现了自己的版本,我担心线程安全和保持连接打开 这个想法和我实现它的方式是线程安全的,以确保每个线程都有自己的db连接吗 我知道,每当我想要改变JNDI查找时,这需要重新启动servlet,我对此没有意见,但是不只是在JDBC方法中执行JNDI查找还有其他缺点吗 我使用d
@WebServlet(name="GetBoardPostCommenters", urlPatterns={"/getBoardPostCommenters"}, loadOnStartup = 1)
public class GetBoardPostCommenters extends HttpServlet
{
private InstrideJndi jndi = null;
private static final long serialVersionUID = 1L;
public void init(ServletConfig servletConfig) throws ServletException
{
super.init(servletConfig);
jndi = new InstrideJndi("GetBoardPostCommenters");
}
public void destroy()
{
jndi.closeConnection();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
BoardPost boardPost;
boardPost = new BoardPost();
boardPost.setId(Long.parseLong(request.getParameter("boardPostId")));
boardPost = BoardPostCommentLikeDAO.getBoardPostCommenters(boardPost, jndi.getDataSource());
request.setAttribute("likerCommenterList", boardPost.getCommenterList());
request.getRequestDispatcher("WEB-INF/util/likerCommenterList.jsp").forward(request, response);
}
}
Bean注释:控制器获取调用此方法以帮助调试的servlet的名称。这种紧密连接就像我在dao方法的最后一部分中通常做的那样
public class InstrideJndi
{
private DataSource dataSource = null;
private Context initialContext = null;
private Context environmentContext = null;
public InstrideJndi(String className)
{
try
{
this.initialContext = new InitialContext();
this.environmentContext = (Context) initialContext.lookup("java:/comp/env");
this.dataSource = (DataSource) environmentContext.lookup("jdbc/instride");
}
catch(NamingException error)
{
System.out.println("Error With JNDI Lookup - " + className + " - " + error.getMessage());
error.printStackTrace();
}
}
public DataSource getDataSource()
{
return this.dataSource;
}
public void closeConnection()
{
if (initialContext != null) try{initialContext.close();} catch(NamingException ignore) {}
if (environmentContext != null) try{environmentContext.close();} catch(NamingException ignore) {}
}
}
每个线程都有自己的数据源引用。您的servlet将是多个请求线程中的一个实例,每个线程调用doGet()
。相反,init()
只在web模块启动时,在servlet实例服务请求之前被调用
另一个技巧-在一次查找中检索容器管理的资源是很常见的
this.dataSource = new InitialContext().lookup("java:/comp/env/jdbc/instride");
我可能是错的,但我通常从不
close()
这些类型的InitialContext实例,除非我特别希望它是一个网络操作(ldap、从远程应用程序服务器查找资源等)。感谢您查看我的问题。要明确的是,我所做的很好(线程安全),我可以用您给出的示例来缩短代码,使其更加清晰。但是我所做的不应该导致问题,对吗?在我的web应用程序的整个生命周期(直到下一次重新启动)中都打开这些查找也可以吗?我没有预见到任何问题。如果您查看使用注入(通过@Resource)获取容器管理的资源(如数据源实例)的教程,它们通常是成员或类级别(静态)变量,因此可以在请求之间共享。只需确保始终从共享数据源获得.close()连接。