问题
I need to create a singleton when Apache Tomcat starts, so that I can access them with servlets. The singleton defines what response will the servlets give.
I wanted to know whether tomcat has a constructor so I can add code so that the singleton can be created.
*edit: after searching a little, I found that I could try using a web service (JAX-WS). I don't know how the jvm treats instances in the web-service though. Can I access the same object on different connections to the WS?
I used bmargulies solution adding these resources to the web.xml descriptor:
<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>
<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':
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:
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()
Edit: Since new InitialContext()'s not really expensive I'm doing that way, It works pretty much well for me
回答1:
Read up on JNDI configuration in Tomcat. The documentation is here. You can define an object to be created, once, when looked up.
回答2:
Alternatively, You can define a Servlet Listener which listens Servlet Context initialized event. When servlet initialized, you can create your object and store it on Servlet Context. Each of your servlets can access this object through servlet context and use it.
回答3:
Alternatively, you can use a startup servlet to initialize the singleton with <load-on-startup>1</load-on-startup>
defined in the web.xml.
来源:https://stackoverflow.com/questions/14792374/how-can-i-create-a-singleton-in-apache-tomcat-startup