首页 > 解决方案 > “单例是每个进程和每个类加载器”是什么意思?

问题描述

《只是春天》一书说:

“请注意,使用 Java Singleton 模式和 Spring Singleton 获得的实例之间存在细微差别。Spring Singleton 是每个上下文或容器的单例,而 Java Singleton 是每个进程和每个类加载器的。”

我确实理解“Spring Singleton 是每个上下文或容器的单例”的含义,但我不明白“Java Singleton 是每个进程和每个类加载器”的含义。你能解释一下最后的qoute吗?

标签: javaspringdesign-patternssingleton

解决方案


纯Java

单例模式是每个类加载器模式。这是由于该模式的实现方式的性质。

public class MySingleton {

  private static final MySingleton INSTANCE = new MySingleton();

  private MySingleton() {}

  public static MySingleton() getInstance() {
    return INSTANCE;
  }
}

每个类加载器都有一个类的副本,因此每个类加载器都会创建一个MySingleton. 因此单例模式是每个类加载器。

问题是因为这是每个类加载器,ClassCastException当类加载器 X 和类加载器 Y 都具有相同的类时,您甚至可能会遇到这种情况。这是因为类标识基于类名 + 加载它的类加载器。(当应用程序还包含这些驱动程序时,这通常是应用程序服务器中的 JDBC 驱动程序的问题)。

春天

AppplicationContext现在 Spring 将为每个(又名上下文或容器)创建一个实例。

@Configuration
public class MyConfiguration {

  @Bean
  public MySingleton mySingleton() {
    return new MySingleton();
  }
}

现在做的时候new AnnotationConfigApplicationContext(MyConfiguration.class)。Spring 将创建一个实例,MySingleton并且每次都会这样做new AnnotationConfigApplicationContext(MyConfiguration.class)。因此,如果您创建另一个实例,您将获得一个新实例。该实例专用于该容器。因此每个容器一个单例。

另请参阅此相关问题/答案。


推荐阅读