Pee*_*ush 87 java singleton spring containers
我们都知道我们在Spring容器中默认使用bean作为单例,如果我们有一个基于Spring框架的Web应用程序那么在这种情况下我们真的需要实现Singleton设计模式来保存全局数据而不是仅仅通过spring创建一个bean .
如果我无法解释我其实想要问的问题,请耐心等待.
use*_*794 54
Spring中的单例bean和单例模式是完全不同的.单例模式表示每个类加载器将创建一个且只有一个特定类的实例.
Spring单例的范围被描述为"每个容器每个bean".每个Spring IoC容器的单个对象实例是bean定义的范围.Spring中的默认范围是Singleton.
即使默认范围是单例,也可以通过指定<bean ../>
element 的scope属性来更改bean的范围.
<bean id=".." class=".." scope="prototype" />
Run Code Online (Sandbox Code Playgroud)
小智 28
Spring中的Singleton作用域意味着Spring上下文中的单个实例
.Spring容器只是一次又一次地返回相同的实例,以便后续调用获取bean.
如果将bean的类编码为singleton,则spring不会打扰,实际上如果该类被编码为singleton,其构造函数为private,则使用BeanUtils.instantiateClass(此处为javadoc )将构造函数设置为可访问并调用它.
或者,我们可以像这样在bean定义中使用factory-method属性
<bean id="exampleBean" class="example.Singleton" factory-method="getInstance"/>
Run Code Online (Sandbox Code Playgroud)
ino*_*nor 19
让我们举一个最简单的例子:你有一个应用程序,你只需使用默认的类加载器.你有一个类,无论出于什么原因,你决定它不应该在应用程序中有多个实例.(想象一下几个人在应用程序的各个部分上工作的场景).
如果您没有使用Spring框架,Singleton模式可确保应用程序中不会有多个类的实例.这是因为你不能通过执行'new'来实例化类的实例,因为构造函数是私有的.获取类实例的唯一方法是调用类的一些静态方法(通常称为"getInstance"),它始终返回相同的实例.
假设您在应用程序中使用Spring框架,只是意味着除了获取类实例的常规方法(返回类实例的新方法或静态方法)之外,您还可以请求Spring来帮助您该类的一个实例和Spring将确保无论何时向它请求该类的实例,它都将返回相同的实例,即使您没有使用Singleton模式编写该类.换句话说,即使该类具有公共构造函数,如果您总是向Spring请求该类的实例,Spring将仅在您的应用程序生命周期内调用该构造函数一次.
通常,如果您使用的是Spring,那么您应该只使用Spring来创建实例,并且您可以为该类创建一个公共构造函数.但是如果你的构造函数不是私有的,那么你并没有真正阻止任何人通过绕过Spring来直接创建类的新实例.
如果你真的想要一个类的单个实例,即使你在你的应用程序中使用Spring并将Spring中的类定义为单例,唯一的方法是使用Singleton模式实现类.这确保了将有一个实例,无论人们使用Spring获取实例还是绕过Spring.
lex*_*ore 10
Spring中的Singleton作用域意味着这个bean只能由Spring实例化一次.与原型范围(每次新实例),请求范围(每个请求一次),会话范围(每个HTTP会话一次)相反.
单例范围在技术上注意到单例设计模式.您不必将bean实现为单例,以便将它们放在单例范围内.
我发现“ 每个容器每个豆”很难理解。我会说“ 每个bean id一个bean ”。让我们举个例子来理解它。我们有一个bean类Sample。我在bean定义中从此类定义了两个bean,例如:
<bean id="id1" class="com.example.Sample" scope="singleton">
<property name="name" value="James Bond 001"/>
</bean>
<bean id="id7" class="com.example.Sample" scope="singleton">
<property name="name" value="James Bond 007"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
因此,当我尝试获取ID为“ id1”的bean时,spring容器将创建一个bean,将其缓存并在id1引用过的地方返回相同的bean。如果我尝试使用id7来获取它,那么将从Sample类创建另一个bean,每次您使用id7引用该bean时,都将对其进行缓存并返回。
单例模式不太可能。在Singlton模式中,总是为每个类加载器创建一个对象。但是在Spring中,将范围设为Singleton并不会限制容器从该类创建许多实例。它只是再次限制了相同ID的新对象的创建,当一个对象被请求使用相同ID时,它返回先前创建的对象。参考
小智 5
两者之间有一个非常根本的区别。在单例设计模式的情况下,每个类加载器只会创建一个类的一个实例,而 Spring 单例则不是这种情况,因为稍后会为每个 IoC 容器的给定 id 创建一个共享 bean 实例。
例如,如果我有一个名为“SpringTest”的类,并且我的 XML 文件如下所示:-
<bean id="test1" class="com.SpringTest" scope="singleton">
--some properties here
</bean>
<bean id="test2" class="com.SpringTest" scope="singleton">
--some properties here
</bean>
Run Code Online (Sandbox Code Playgroud)
因此,现在在主类中,如果您检查上述两个的引用,它将返回 false,根据 Spring 文档:-
当一个 bean 是单例时,只会管理该 bean 的一个共享实例,并且对具有与该 bean 定义匹配的 id 或多个 id 的 bean 的所有请求都将导致 Spring 容器返回一个特定的 bean 实例
在我们的例子中,类是相同的,但我们提供的 id 不同,因此导致创建两个不同的实例。