在使用Spring Core面试职位时,我经常问一个问题:“ Spring Singleton示波器是什么意思?”
大多数时候,我得到的答案是:“ Spring Singleton范围仅管理容器中的一个对象。”
得到这个答案后,我问下一个问题:“请告诉我下面程序的输出是什么。”
Spring.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="scopeTest" class="com.example.scope.Scope" scope="singleton"> <property name="name" value="Shamik Mitra"/> </bean> <bean id="scopeTestDuplicate" class="com.example.scope.Scope" scope="singleton"> <property name="name" value="Samir Mitra"/> </bean> </beans>
Scope.java:
package com.example.scope; public class Scope { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Scope [name=" + name + "]"; } }
Main class:
package com.example.scope; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext( "configFiles/Scope.xml"); Scope scope = (Scope) ctx.getBean("scopeTest"); Scope scopeDuplicate = (Scope) ctx.getBean("scopeTestDuplicate"); System.out.println(scope == scopeDuplicate); System.out.println(scope + "::" + scopeDuplicate); } }
在这里,我创建了Scope类的两个bean,并使Spring Scope为单例,现在检查引用。
这是受访者有时会感到困惑的地方。通常,我会得到三种类型的答案:
此代码将无法编译。这将在运行时引发错误,因为您无法在XML中使用Singleton Scope定义同一类的两个Sspring bean。(非常罕见)
由于容器维护一个对象,因此引用检查将返回true。这两个bean定义将返回相同的对象,因此内存位置将相同。(经常)
引用检查将返回false,这意味着Spring Singletons不能像之前所说的那样工作。(几个)
第三个答案是正确的答案。Spring Singleton不能像Java Singleton那样工作。
如果看到程序的输出,我们将理解它将返回两个不同的实例。因此,尽管Scope是单例,但在一个容器中,可能会有多个对象。
输出:
Reference Check ::false Scope [name=Shamik Mitra]::Scope [name=Samir Mitra]
所以,让我们再问一个问题。“ Spring Singleton Scope是什么意思?”
根据Spring文档:
“当一个bean是单例时,将仅管理该bean的一个共享实例,并且所有具有与该bean定义匹配的id或id的bean请求都将导致该特定的bean实例由Spring容器返回。
换句话说,当您定义一个bean定义并且其作用域为单例时,Spring IoC容器将为该bean定义定义的对象创建一个实例。这个单一实例将存储在此类单例bean的缓存中,并且对该命名bean的所有后续请求和引用将导致返回缓存的对象。”
因此很明显,对于给定的id,Spring容器在单例缓存中仅维护一个共享实例。
在我的示例中,我使用了两个不同的ID(scopeTest和ScopeTestDuplicate),因此Spring容器创建了同一类的两个实例,并将它们与各自的ID绑定在一起,然后将它们存储在Singleton缓存中。
您可以将Spring容器视为管理键值对,其中键是bean的ID或名称,而值是bean本身。因此,对于给定的键,它维护一个Singleton。因此,如果我们使用该键作为对其他Bean的引用,则将相同的Bean注入到其他Bean。
总而言之,Spring与每个IoC容器为给定的id保证了一个完全共享的bean实例,这与Java Singletons不同,在Java Singletons中,Singleton硬编码对象的范围,以便每个ClassLoader只能创建一个特定类的一个实例。
原文链接:http://codingdict.com