【问题标题】:What is the meaning of "Singleton is per process and per class loader"?“单例是每个进程和每个类加载器”是什么意思?
【发布时间】:2020-11-03 08:02:44
【问题描述】:
《只是春天》这本书说:
“请注意,使用 Java Singleton 模式和 Spring Singleton 获得的实例之间存在细微差别。Spring Singleton 是每个上下文或容器的单例,而 Java Singleton 是每个进程和每个类加载器的。”
我确实理解“Spring Singleton 是每个上下文或容器的单例”是什么意思,但我不明白“Java Singleton 是每个进程和每个类加载器”的意思。你能解释一下最后的报价吗?
【问题讨论】:
标签:
java
spring
design-patterns
singleton
【解决方案1】:
纯 Java
单例模式是每个类加载器模式。这是由于该模式实施方式的性质所致。
public class MySingleton {
private static final MySingleton INSTANCE = new MySingleton();
private MySingleton() {}
public static MySingleton() getInstance() {
return INSTANCE;
}
}
每个类加载器都有一个类的副本,因此每个类加载器都会创建一个MySingleton 的实例。因此单例模式是每个类加载器。
问题在于,因为这是每个类加载器,当类加载器 X 和类加载器 Y 都具有相同的类时,您甚至可能会遇到ClassCastException。这是因为类标识基于类名 + 加载它的类加载器。(当应用程序还包含这些驱动程序时,这通常是应用程序服务器中的 JDBC 驱动程序的问题)。
春天
现在 Spring 将为每个 AppplicationContext(又名上下文或容器)创建一个实例。
@Configuration
public class MyConfiguration {
@Bean
public MySingleton mySingleton() {
return new MySingleton();
}
}
现在在做new AnnotationConfigApplicationContext(MyConfiguration.class) 时。 Spring 将创建一个MySingleton 的实例,并且每次创建new AnnotationConfigApplicationContext(MyConfiguration.class) 时都会这样做。因此,如果您创建另一个实例,您将获得一个新实例。该实例专用于该容器。因此每个容器一个单例。
另见this related问题/答案。