Bean作用域定义是如何创建Bean并将其从Spring容器返回给Bean请求者的。默认情况下,所有bean的范围都是单例。每当需要该bean时,例如在注入或使用getBean()应用程序上下文中的方法进行调用时,spring容器将始终返回相同的bean 。
Spring容器中定义了五种类型的bean作用域:
范围 | 描述 |
---|---|
singleton | 每个Spring容器将Bean定义范围限制为单个Bean实例。当创建bean时未定义范围时,这是默认范围。 |
prototype | 对bean进行范围调整,以允许多次创建bean。每次需要bean时都会创建一个新bean。 |
request | 将bean定义的作用域限定为单个HTTP请求。* |
session | 将bean定义的作用域限定为单个HTTP会话。* |
global-session | 将bean定义的作用域限定为全局HTTP会话。* |
*)仅在使用支持Web的Spring上下文时有效。
让我们看看Singleton和Prototype作用域之间的区别。首先,我们将创建我们的DummyService课程。
package org.nhooo.example.spring.dummy; public class DummyService { private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
默认情况下,如果未定义任何范围,它将是单例。
<?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.xsd"> <bean id="service"/> </beans>
现在创建一个程序来运行我们的示例。首先将使用singleton.xml作为配置运行它。
package org.nhooo.example.spring.dummy; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class BeanScopeDemo { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("singleton.xml"); DummyService serviceA = (DummyService) context.getBean("service"); serviceA.setMessage("Hello From A"); System.out.println("Message A = " + serviceA.getMessage()); DummyService serviceB = (DummyService) context.getBean("service"); System.out.println("Message B = " + serviceB.getMessage()); } }
单例配置的输出为:
Message A = Hello From A Message B = Hello From A
上面的输出显示所打印的消息serviceB与相同serviceA。我们甚至没有在serviceB显式设置消息。它输出相同的消息,因为该getBean()方法实际上为serviceA和返回相同的bean serviceB。这是单例范围。
要将范围更改为原型,请使用scopebean元素中的属性,如下所示。
<?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.xsd"> <bean id="service" scope="prototype"/> </beans>
package org.nhooo.example.spring.dummy; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class BeanScopePrototypeDemo { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("prototype.xml"); DummyService serviceA = (DummyService) context.getBean("service"); serviceA.setMessage("Hello From A"); System.out.println("Message A = " + serviceA.getMessage()); DummyService serviceB = (DummyService) context.getBean("service"); System.out.println("Message B = " + serviceB.getMessage()); } }
现在,如果您尝试再次运行同一程序,但将配置更改prototype.xml为以下内容,则会得到以下输出:
Message A = Hello From A Message B = null
在serviceB现在打印不同的消息。这是使用prototype示波器的效果。当我们调用时,getBean()将根据请求创建一个新bean。