Bean的作用域
Bean的作用域
默认情况下,所有Spring Bean都是单例的(整个Spring应用中,Bean的实例只有一个)。可以再<bean>元素中添加scope属性来配置Spring Bean的作用范围。
scope作用域范围:
作用范围 | 描述 |
---|---|
singleton | 默认值,单例模式,表示在 Spring 容器中只有一个 Bean 实例 |
prototype | 原型模式,表示每次通过 Spring 容器获取 Bean 时,容器都会创建一个新的 Bean 实例。 |
request | 每次 HTTP 请求,容器都会创建一个 Bean 实例。该作用域只在当前 HTTP Request 内有效。 |
session | 同一个 HTTP Session 共享一个 Bean 实例,不同的 Session 使用不同的 Bean 实例。该作用域仅在当前 HTTP Session 内有效。 |
application | 同一个 Web 应用共享一个 Bean 实例,该作用域在当前 ServletContext 内有效。 与 singleton 类似,但 singleton 表示每个 IoC 容器中仅有一个 Bean 实例,而一个 Web 应用中可能会存在多个 IoC 容器,但一个 Web 应用只会有一个 ServletContext,也可以说 application 才是 Web 应用中货真价实的单例模式。 |
websocket | websocket 的作用域是 WebSocket ,即在整个 WebSocket 中有效。 |
注意:在以上 6 种 Bean 作用域中,除了 singleton 和 prototype 可以直接在常规的 Spring IoC 容器(例如 ClassPathXmlApplicationContext)中使用外,剩下的都只能在基于 Web 的 ApplicationContext 实现(例如 XmlWebApplicationContext)中才能使用,否则就会抛出一个 IllegalStateException 的异常。
单例模式singleton
singleton是Spring Ioc容器默认的作用域,此时容器中只会存在一个共享的Bean实例。这个Bean实例会被存储在高速缓存中,所有对于这个Bean的请求和引用,只要id与这个Bean定义相匹配,都会返回这个缓存中的对象实例。
在 Spring 配置文件中,可以使用 <bean> 元素的 scope 属性,将 Bean 的作用域定义成 singleton,其配置方式如下所示:(不声明scope属性默认也是singleton)
<bean id="..." class="..." scope="singleton"/>
代码示例:
- 实体类
package org.demo5;
public class SingletonBean {
private String str;
public void setStr(String str) {
this.str = str;
}
}
- 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="singletonBean" class="org.demo5.SingletonBean" scope="singleton">
<property name="str" value="bdqn"></property>
</bean>
</beans>
- main方法
package org.demo5;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
//private static final Log LOGGER= LogFactory.getLog(MainApp.class);
public static void main(String[] args) {
//创建bean工厂
ApplicationContext context=new ClassPathXmlApplicationContext("demo5beans.xml");
//取bean
SingletonBean sBean1=context.getBean("singletonBean",SingletonBean.class);
SingletonBean sBean2=context.getBean("singletonBean",SingletonBean.class);
System.out.println(sBean1);
System.out.println(sBean2);
}
}
运行结果:
org.demo5.SingletonBean@696da30b
org.demo5.SingletonBean@696da30b
从控制台的输出可以看出,两次获得的 Bean 实例的地址完全一样,这说明 IoC 容器只创建了一个 singletonBean 实例。由于 singleton 是 Spring IoC 容器的默认作用域,因此即使省略 scope 属性,控制台的输出结果也一样的。
原型模式prototype
当Bean定义的作用域为prototype,Spring容器会在每次请求该Bean时,都会创建一个新的Bean实例。
代码示例:
-
实体类
package org.demo5; public class PrototypeBean { private String str; public void setStr(String str) { this.str = str; } }
-
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"> <!--singleton--> <bean id="singletonBean" class="org.demo5.SingletonBean" scope="singleton"> <property name="str" value="singletonBean"/> </bean> <!--prototype--> <bean id="prototypeBean" class="org.demo5.PrototypeBean" scope="prototype"> <property name="str" value="prototypeBean"/> </bean> </beans>
-
main方法类
package org.demo5;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class MainApp { //private static final Log LOGGER= LogFactory.getLog(MainApp.class); public static void main(String[] args) { //创建bean工厂 ApplicationContext context=new ClassPathXmlApplicationContext("demo5beans.xml"); //singleton SingletonBean sBean1=context.getBean("singletonBean",SingletonBean.class); SingletonBean sBean2=context.getBean("singletonBean",SingletonBean.class); System.out.println(sBean1); System.out.println(sBean2); //prototype PrototypeBean pBean1=context.getBean("prototypeBean",PrototypeBean.class); PrototypeBean pBean2=context.getBean("prototypeBean",PrototypeBean.class); System.out.println(pBean1); System.out.println(pBean2); }}
-
运行结果
org.demo5.PrototypeBean@be35cd9 org.demo5.PrototypeBean@4944252c
从运行结果可以看出,两次输出的内容并不相同,这说明在 prototype 作用域下,Spring 容器创建了两个不同的 prototypeBean 实例。
- 点赞
- 收藏
- 关注作者
评论(0)