"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。