Plain Java
The singleton pattern is a per classloader pattern. This is due to the nature of how that pattern is implemented.
public class MySingleton {
private static final MySingleton INSTANCE = new MySingleton();
private MySingleton() {}
public static MySingleton() getInstance() {
return INSTANCE;
}
}
Each classloader has a copy of the class and thus each classloader will create an instance of MySingleton
. And thus the singleton pattern is per classloader.
The problem is that because this is per classloader you might even run into a ClassCastException
when classloader X and classloader Y have both the same class. This is because class identity is based on the classname + the classloader it is loaded in. (This is often an issue with JDBC Drivers in an application server, when the application also includes those drivers).
Spring
Now Spring will create an instance per AppplicationContext
(aka the context or container).
@Configuration
public class MyConfiguration {
@Bean
public MySingleton mySingleton() {
return new MySingleton();
}
}
Now when doing new AnnotationConfigApplicationContext(MyConfiguration.class)
. Spring will create an instance of MySingleton
and will so do so each time one does new AnnotationConfigApplicationContext(MyConfiguration.class)
. So if you create another one, you will get a new instance. The instance is dedicated to that container. Hence a singleton per container.
See also this related question/answer.