Singletondevise模式与Spring容器中的Singleton bean

众所周知,在Spring容器中,默认情况下bean是singleton,如果我们有一个基于Spring框架的Web应用程序,那么我们真的需要实现Singletondevise模式来保存全局数据,而不是通过Spring创build一个bean 。

如果我无法解释我实际上想问的问题,请耐心等待。

Spring中的singleton bean和单例模式是完全不同的。 Singleton模式表示,每个类加载器都会创build一个特定类的唯一一个实例。

Spring单例的范围被描述为“每个bean每个容器”。 这是每个Spring IoC容器对单个对象实例的bean定义的范围。 Spring中的默认范围是Singleton。

即使默认范围是singleton,也可以通过指定<bean ../>元素的scope属性来更改bean的范围。

 <bean id=".." class=".." scope="prototype" /> 

Spring中的Singleton范围意味着Spring环境中的单个实例。
Spring容器只是一次又一次地返回相同的实例,以便随后的调用来获取bean。

而且,如果bean的类被编码为单例,Spring并不打扰,事实上,如果类被编码为单例,其构造函数为private,那么Spring使用BeanUtils.instantiateClass(javadoc here )来设置构造函数为可访问和调用它。

或者,我们可以像这样在bean定义中使用一个工厂方法属性

  <bean id="exampleBean" class="example.Singleton" factory-method="getInstance"/> 

我们举一个最简单的例子:你有一个应用程序,你只需要使用默认的类加载器。 你有一个类,无论出于何种原因,你决定在应用程序中不应该有多个实例。 (想想几个人在应用程序中工作的场景)。

如果你不使用Spring框架,Singleton模式可以确保你的应用程序中不会有多于一个类的实例。 这是因为您不能通过执行“new”来实例化类的实例,因为构造函数是私有的。 获得类的实例的唯一方法是调用一些总是返回相同实例的类的静态方法(通常称为“getInstance”)。

说你在你的应用程序中使用Spring框架,就意味着除了获取类的实例的常规方法(返回类的实例的新方法或静态方法)之外,还可以请求Spring让你该类的一个实例和Spring将确保无论何时你要求它为该类的一个实例,它将总是返回相同的实例,即使你没有使用Singleton模式写这个类。 换句话说,即使这个类有一个公共的构造函数,如果你总是向Spring请求这个类的一个实例,那么Spring在你的应用程序的整个生命周期中只会调用这个构造函数。

通常情况下,如果你使用的是Spring,你只能使用Spring来创build实例,并且你可以有一个类的公共构造函数。 但是,如果你的构造函数不是私有的,那么就不能真正阻止任何人直接创build类的新实例。

如果你确实需要一个类的实例,那么即使你在你的应用程序中使用了Spring,并且在Spring中定义了这个类是一个单例,唯一的方法就是使用Singleton模式来实现这个类。 这确保了会有一个实例,无论人们使用Spring来获得一个实例还是绕过Spring。

Spring中的Singleton范围意味着这个bean将仅被Spring实例化一次。 与原型范围(每次新实例)相比,请求范围(每个请求一次),会话范围(每个HTTP会话一次)。

Singleton范围在技术上与单件devise模式有关。 你不需要实现你的bean作为单身人士,把他们放在单身人士的范围内。

Spring中的Singleton bean和基于Singletondevise模式的类是完全不同的。

Singleton模式确保每个类加载器都创build一个特定类的唯一一个实例,因为Spring单例bean的范围被描述为“每个容器每个bean”。 Spring中的Singleton范围意味着这个bean将仅被Spring实例化一次。 Spring容器只是一次又一次地返回相同的实例,以便随后的调用来获取bean。

spring的“singleton”正在使用bean factory获取实例,然后caching它; 哪个单例devise模式严格,实例只能从静态获取方法中获取,而且不能公开实例化。

EX:“每个容器每个bean”。

  <bean id="myBean" class="com.spring4hibernate4.TestBean"> <constructor-arg name="i" value="1"></constructor-arg> <property name="name" value="1-name"></property> </bean> <bean id="testBean" class="com.spring4hibernate4.TestBean"> <constructor-arg name="i" value="10"></constructor-arg> <property name="name" value="10-name"></property> </bean> </beans> public class Test { @SuppressWarnings("resource") public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("ws.xml"); TestBean teatBean = (TestBean) ac.getBean("testBean"); TestBean myBean1 = (TestBean) ac.getBean("myBean"); System.out.println("a : " + teatBean.test + " : " + teatBean.getName()); teatBean.setName("a TEST BEAN 1"); System.out.println("uPdate : " + teatBean.test + " : " + teatBean.getName()); System.out.println("a1 : " + myBean1.test + " : " + myBean1.getName()); myBean1.setName(" a1 TEST BEAN 10"); System.out.println("a1 update : " + teatBean.test + " : " + myBean1.getName()); } } public class TestBean { public int test = 0; public String getName() { return name; } public void setName(String name) { this.name = name; } private String name = "default"; public TestBean(int i) { test += i; } } 

JAVA SINGLETON:

 public class Singleton { private static Singleton singleton = new Singleton(); private int i = 0; private Singleton() { } public static Singleton returnSingleton() { return singleton; } public void increment() { i++; } public int getInt() { return i; } } public static void main(String[] args) { System.out.println("Test"); Singleton sin1 = Singleton.returnSingleton(); sin1.increment(); System.out.println(sin1.getInt()); Singleton sin2 = Singleton.returnSingleton(); System.out.println("Test"); sin1.increment(); System.out.println(sin1.getInt()); }