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
只被调用了一次。在第一次执行之后,javabean
MyBean
似乎已经存储在Tomcat中。然后,
MyBean
被每个请求重用。无论何时在浏览器中重新键入URL,响应始终显示与第一个相同的时间戳。以下是可能有帮助的元素列表:

  • MyBean:由
    MyBeanFactory
  • MyBeanFactory:实现
    javax.naming.spi.ObjectFactory的工厂
  • context.xml:资源的上下文描述符,位于META-INF文件夹中
  • web.xml:部署描述符
  • MyAction:http servlet
  • 控制台
谁能告诉我为什么只调用一次MyBeanFactory,以及是否可以更改此功能?因为我需要修改工厂,以便与服务器中的另一个进程建立套接字。看


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
------