"Singleton is per process and per class loader"是什么意思?
What is the meaning of "Singleton is per process and per class loader"?
“只是 Spring”书说:
”请注意,使用Java单例模式和Spring单例模式获得的实例之间存在细微差别。Spring单例是每个上下文或容器的单例,而Java 单例是每个进程和每个 class 加载器。"
我明白“Spring 单例是每个上下文或容器的单例”是什么意思,但我不明白“Java 单例是每个进程和每个 class”装载机”的意思。你能解释一下最后一句吗?
普通Java
单例模式是每个 classloader 模式。这是由于该模式的实施方式的性质。
public class MySingleton {
private static final MySingleton INSTANCE = new MySingleton();
private MySingleton() {}
public static MySingleton() getInstance() {
return INSTANCE;
}
}
每个 classloader 都有一个 class 的副本,因此每个 classloader 都会创建一个 MySingleton
的实例。因此单例模式是每个 classloader.
问题是,因为这是每个 classloader,当 classloader X 和 classloader Y 时,您甚至可能 运行 进入 ClassCastException
两者相同 class。这是因为 class 身份基于 classname + 它加载的 classloader。(这通常是应用程序服务器中 JDBC 驱动程序的问题,当应用程序还包括那些驱动程序时)。
Spring
现在 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 question/answer。
“只是 Spring”书说:
”请注意,使用Java单例模式和Spring单例模式获得的实例之间存在细微差别。Spring单例是每个上下文或容器的单例,而Java 单例是每个进程和每个 class 加载器。"
我明白“Spring 单例是每个上下文或容器的单例”是什么意思,但我不明白“Java 单例是每个进程和每个 class”装载机”的意思。你能解释一下最后一句吗?
普通Java
单例模式是每个 classloader 模式。这是由于该模式的实施方式的性质。
public class MySingleton {
private static final MySingleton INSTANCE = new MySingleton();
private MySingleton() {}
public static MySingleton() getInstance() {
return INSTANCE;
}
}
每个 classloader 都有一个 class 的副本,因此每个 classloader 都会创建一个 MySingleton
的实例。因此单例模式是每个 classloader.
问题是,因为这是每个 classloader,当 classloader X 和 classloader Y 时,您甚至可能 运行 进入 ClassCastException
两者相同 class。这是因为 class 身份基于 classname + 它加载的 classloader。(这通常是应用程序服务器中 JDBC 驱动程序的问题,当应用程序还包括那些驱动程序时)。
Spring
现在 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 question/answer。