简体   繁体   English

如何在Apache Tomcat启动中创建单例

[英]How can I create a singleton in Apache Tomcat startup

I need to create a singleton when Apache Tomcat starts, so that I can access them with servlets. 我需要在Apache Tomcat启动时创建一个单例,以便可以使用servlet访问它们。 The singleton defines what response will the servlets give. 单例定义了servlet将给出什么响应。

I wanted to know whether tomcat has a constructor so I can add code so that the singleton can be created. 我想知道tomcat是否具有构造函数,以便添加代码以便创建单例。

*edit: after searching a little, I found that I could try using a web service (JAX-WS). *编辑:稍作搜索后,我发现我可以尝试使用Web服务(JAX-WS)。 I don't know how the jvm treats instances in the web-service though. 我不知道jvm如何处理Web服务中的实例。 Can I access the same object on different connections to the WS? 我可以在与WS的不同连接上访问同一对象吗?

I used bmargulies solution adding these resources to the web.xml descriptor: 我使用bmargulies解决方案将这些资源添加到web.xml描述符中:

<resource-env-ref>
  <description>
     Factory for the Arduino Connection
  </description>
  <resource-env-ref-name>
     arduino/ArduinoConnectionFactory
  </resource-env-ref-name>
  <resource-env-ref-type>
     br.com.evans.jndi.basic.ArduinoConnection
  </resource-env-ref-type>
</resource-env-ref>

This to the context.xml : 这到context.xml

<Context>
  <Resource name="arduino/ArduinoConnectionFactory" auth="Container"
        type="br.com.evans.jndi.basic.ArduinoConnection"
        factory="br.com.evans.jndi.basic.ArduinoConnectionFactory"/>
</Context>

Created the singleton class: 创建了单例类:

public enum ArduinoConnection implements SerialPortEventListener {
    INSTANCE;
    public void initialize() {...}
}

Created the singleton 'factory': 创建单例“ factory”:

public class ArduinoConnectionFactory implements ObjectFactory {

    public ArduinoConnectionFactory() {
        ArduinoConnection.INSTANCE.initialize();
        try {
            Thread.sleep(1800);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public Object getObjectInstance(Object obj, Name name, 
        Context nameCtx,Hashtable environment) throws NamingException {
            // Return the customized instance
            return (ArduinoConnection.INSTANCE);
        }
    }

and finally this to a get function in a servlet: 最后,这是servlet中的get函数:

    Context initCtx;
    try {
        initCtx = new InitialContext();
        Context envCtx = (Context) initCtx.lookup("java:comp/env");
        ArduinoConnection arduino = (ArduinoConnection) envCtx.lookup("arduino/ArduinoConnectionFactory");
        arduino.doSomething();
    } catch (NamingException e) {
        System.out.println("Something went wrong!");
        e.printStackTrace();
    }

My problem now is to know how do I call those methods from another servlet without making a new InitialContext() 我现在的问题是要知道如何在不创建新的InitialContext()的情况下从另一个servlet调用这些方法。

Edit: Since new InitialContext()'s not really expensive I'm doing that way, It works pretty much well for me 编辑:由于新的InitialContext()并不是真的很昂贵,所以对我来说效果很好

Read up on JNDI configuration in Tomcat. 阅读Tomcat中的JNDI配置。 The documentation is here . 文档在这里 You can define an object to be created, once, when looked up. 您可以一次查找一次定义要创建的对象。

Alternatively, You can define a Servlet Listener which listens Servlet Context initialized event. 或者,您可以定义一个Servlet Listener ,以监听Servlet Context初始化的事件。 When servlet initialized, you can create your object and store it on Servlet Context. 初始化Servlet时,可以创建对象并将其存储在Servlet Context中。 Each of your servlets can access this object through servlet context and use it. 您的每个servlet都可以通过servlet上下文访问此对象并使用它。

另外,您可以使用启动Servlet通过web.xml中定义的<load-on-startup>1</load-on-startup>初始化单例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM