gpt4 book ai didi

java - 在 servlet 的 init 参数中进行 JNDI 查找是个好主意吗?

转载 作者:行者123 更新时间:2023-12-02 07:06:49 24 4
gpt4 key购买 nike

我目前正在构建一个 Java EE Web 应用程序并发现 this这篇文章给了我一些关于如何构建更好的应用程序的重要指导。第一个技巧是“使用 HttpServlet init() 方法缓存数据”。这听起来像是一个天才的想法,但现在我已经实现了自己的版本,我担心线程安全和保持连接打开。

  1. 这个想法以及我实现它的方式是否是线程安全的,以确保每个线程都有自己的数据库连接?
  2. 我知道,每当我想要更改 JNDI 查找时,都需要重新启动 servlet,我对此表示同意,但是如果不只在 JDBC 方法中进行 JNDI 查找,还会有其他缺点吗?
  3. 我使用 destroy 方法关闭上下文变量的方式是一个聪明的主意吗?还是说这在大量线程或任何其他障碍的情况下不起作用?

这里有一些代码可以让您了解我如何实现这个想法。在我开始在我的 40 个其他 servlet 上实现此操作之前,我希望获得有关我的第一个实现的一些指导。非常感谢您的阅读。哦,如果有帮助的话,我也可以添加 dao 方法。

Servlet 注释: 在 init 中,我只是调用一个执行所有 JNDI 功能的 Bean,以便更容易将其添加到多个 Servlet。然后在servlt中我将数据源发送到要使用的dao方法。我还认为在启动时添加负载是明智之举,这样我就可以在启动服务器时查看 JNDI 是否立即工作。

@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 注释: Controller 获取调用此方法的 servlet 的名称以帮助调试。关闭连接执行的是我通常在 dao 方法的finally 中执行的操作。

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、从远程应用程序服务器进行资源查找、等)。

关于java - 在 servlet 的 init 参数中进行 JNDI 查找是个好主意吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15994804/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com