Java 为什么在Tomcat中只能调用一次JNDI资源?
在我学习的时候,已经建立了一个定制的豆子工厂,名为Java 为什么在Tomcat中只能调用一次JNDI资源?,java,tomcat,jakarta-ee,jndi,Java,Tomcat,Jakarta Ee,Jndi,在我学习的时候,已经建立了一个定制的豆子工厂,名为MyBeanFactory。它为我的web应用程序提供外部资源。第一次,我们假设它提供了当前系统时间戳 然而,我意识到在第一次请求时,MyBeanFactory只被调用了一次。在第一次执行之后,javabeanMyBean似乎已经存储在Tomcat中。然后,MyBean被每个请求重用。无论何时在浏览器中重新键入URL,响应始终显示与第一个相同的时间戳。以下是可能有帮助的元素列表: MyBean:由MyBeanFactory MyBeanFact
MyBeanFactory
。它为我的web应用程序提供外部资源。第一次,我们假设它提供了当前系统时间戳
然而,我意识到在第一次请求时,MyBeanFactory
只被调用了一次。在第一次执行之后,javabeanMyBean
似乎已经存储在Tomcat中。然后,MyBean
被每个请求重用。无论何时在浏览器中重新键入URL,响应始终显示与第一个相同的时间戳。以下是可能有帮助的元素列表:
- MyBean:由
MyBeanFactory
- MyBeanFactory:实现
javax.naming.spi.ObjectFactory的工厂
- context.xml:资源的上下文描述符,位于META-INF文件夹中
- web.xml:部署描述符
- MyAction:http servlet
- 控制台
MyBean
public class MyBean {
private String foo = "Default Foo";
private long bar = 0;
public String getFoo() { return (this.foo); }
public void setFoo(String foo) { this.foo = foo; }
public long getBar() { return (this.bar); }
public void setBar(long bar) { this.bar = bar; }
}
public class MyAction extends HttpServlet {
// ...
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("doGet");
response.getWriter()
.append("Hello coming from ")
.append(request.getRequestURI());
Context initCtx = null;
try {
System.out.println("initCtx");
initCtx = new InitialContext();
} catch (NamingException e) {
e.printStackTrace();
}
Context envCtx = null;
try {
System.out.println("envCtx");
envCtx = (Context) initCtx.lookup("java:comp/env");
} catch (NamingException e) {
e.printStackTrace();
}
MyBean bean;
try {
System.out.println("lookup");
bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");
response.getWriter()
.append("foo = " + bean.getFoo() + ", ")
.append("bar = " + bean.getBar() + ";");
} catch (NamingException e) {
e.printStackTrace();
}
System.out.println("------");
}
}
MyBeanFactory
public class MyBeanFactory implements ObjectFactory {
@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable<?, ?> environment) throws NamingException {
System.out.println("MyBeanFactory starts");
MyBean bean = new MyBean();
bean.setBar(System.currentTimeMillis());
// Return the customized instance
return bean;
}
}
控制台
Dec 28, 2015 7:41:03 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 412 ms
doGet
initCtx
envCtx
lookup
MyBeanFactory starts // called only once
------
doGet
initCtx
envCtx
lookup
------
doGet
initCtx
envCtx
lookup
------
您显示的
元素具有超出这些属性的属性,特别是“factory”和“bar”。然而,也许文档中错误地省略了前一个属性,因为一些示例使用了它
无论如何,我想提请大家注意“singleton”属性。当该属性的值为
true
(默认值)时,资源将被视为一个单实例,由上下文维护一个实例,并在所有用户之间共享。这似乎就是你描述的行为。如果将该属性添加到声明中,其值为false
,则该资源的每次查找都应检索一个新实例。由于您正在定义一个servlet上下文资源,因此期望给定上下文只有一个实例似乎是合理的。上下文资源的全部要点是共享。话虽如此,您引用Tomcat 7却使用了该版本的Tomcat中没有记录的配置属性,这让我有点厌烦。您实际使用的是哪个版本?@JohnBollinger我使用的是tomcat 8.0.21
public class MyAction extends HttpServlet {
// ...
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("doGet");
response.getWriter()
.append("Hello coming from ")
.append(request.getRequestURI());
Context initCtx = null;
try {
System.out.println("initCtx");
initCtx = new InitialContext();
} catch (NamingException e) {
e.printStackTrace();
}
Context envCtx = null;
try {
System.out.println("envCtx");
envCtx = (Context) initCtx.lookup("java:comp/env");
} catch (NamingException e) {
e.printStackTrace();
}
MyBean bean;
try {
System.out.println("lookup");
bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");
response.getWriter()
.append("foo = " + bean.getFoo() + ", ")
.append("bar = " + bean.getBar() + ";");
} catch (NamingException e) {
e.printStackTrace();
}
System.out.println("------");
}
}
Dec 28, 2015 7:41:03 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 412 ms
doGet
initCtx
envCtx
lookup
MyBeanFactory starts // called only once
------
doGet
initCtx
envCtx
lookup
------
doGet
initCtx
envCtx
lookup
------