在 Tomcat 中,单例设计模式被广泛使用,例如 org.apache.catalina.core.StandardHost 类就是一个单例。
StandardHost 类表示 Tomcat 中的一个虚拟主机,它是 org.apache.catalina.Container 接口的实现类。Tomcat 中的 org.apache.catalina.Container 接口表示一个容器,即一个可以包含其他组件的组件。
在 Tomcat 中,每个 Container 对象都有一个父容器和一组子容器。在 StandardHost 类中,只有一个实例会被创建,并且这个实例会在 Tomcat 启动时被初始化。
以下是 StandardHost 类的一部分代码,展示了如何使用单例模式创建一个唯一的实例:
public class StandardHost extends ContainerBase implements Host {
/**
* The application root for this Host.
*/
protected String appBase = "webapps";
/**
* The Java class name of the context configuration class we use.
*/
protected String contextClass = "org.apache.catalina.core.StandardContext";
/**
* The single instance of the Mapper listener that is installed at the host level.
*/
protected final MapperListener mapperListener = new MapperListener(this);
/**
* The set of aliases for this Host.
*/
protected String[] aliases = new String[0];
/**
* The single Servlet instance for this Host.
*/
protected final transient Context context = (Context) Class.forName(contextClass).newInstance();
/**
* The flag that indicates if this host is auto deploy enabled.
*/
protected boolean autoDeploy = true;
/**
* The flag that indicates if this host is deploy on startup.
*/
protected boolean deployOnStartup = true;
/**
* The flag that indicates if this host is deploy XML contexts.
*/
protected boolean deployXML = true;
/**
* The flag that indicates if this host is unpack WARs.
*/
protected boolean unpackWARs = true;
/**
* The set of Valves associated with this Host.
*/
protected final ValveContext valveContext = new StandardHostValveContext();
// 构造函数私有化,防止外部创建实例
private StandardHost() {
super();
pipeline.setBasic(new StandardHostValve());
cluster = new SimpleTcpCluster();
}
/**
* The singleton instance of this class.
*/
private static StandardHost instance;
/**
* Returns the singleton instance of this class.
*/
public static synchronized StandardHost getInstance() {
if (instance == null) {
instance = new StandardHost();
}
return instance;
}
/**
* Starts this host.
*/
public void start() throws LifecycleException {
if (!started) {
// 设置状态
setState(LifecycleState.STARTING);
// 初始化相关配置
init();
// 启动相关组件
super.start();
}
}
// ...
}
在上面的代码中,StandardHost 类的构造函数是私有的,这意味着外部代码无法创建 StandardHost 对象。而在 getInstance() 方法中,如果实例不存在,则会创建一个新的 StandardHost 实例,并将其保存在 instance 变量中。这样,无论多少次调用