Spring Bean的作用域

Spring Bean的作用域

目前Bean的作用域有以下6种,

作用域描述
singleton在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,bean作用域范围的默认值。
prototype每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean()。
request每次HTTP请求都会创建一个新的Bean,该作用域仅适用于web的Spring WebApplicationContext环境。
session同一个HTTP Session共享一个Bean,不同Session使用不同的Bean。该作用域仅适用于web的Spring WebApplicationContext环境。
application限定一个Bean的作用域为ServletContext的生命周期。该作用域仅适用于web的Spring WebApplicationContext环境。
global-session全局session,集群下的session,如果不是集群环境,和session没去别。

1.作用域为Singleton的Bean,默认也是Singleton

作用域为Singleton的Bean只会在IOC容器中创建一个共享的bean实例,每次从IOC容器中拿到的Bean都是同一个。

下面举一个例子来说明

1、首先创建一个Bean

public class Student {
    private String study;

    public String getStudy() {
        return study;
    }

    public void setStudy(String study) {
        this.study = study;
    }
}

2、在Spring文件配置上面这个Bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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 http://www.springframework.org/schema/aop   http://www.springframework.org/schema/aop/spring-aop.xsd">

       <bean id="student" class="com.springtest2.scope.Student" scope="singleton" />

</beans>

3、编写测试类

 @Test
    public void testSingleton(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext5.xml");
        Student student = (Student) context.getBean("student");
        student.setStudy("我在学英语。。。");
        System.out.println(student.getStudy());
        Student student2 = (Student) context.getBean("student");
        System.out.println(student2.getStudy());
        System.out.println(student == student2);
    }

4、打印结果

我在学英语。。。
我在学英语。。。
true

2.作用域为prototype的Bean

当bean作用域scopeprototype的时候,每次从IOC容器中获取的Bean都是一个新创建的。prototype是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象

这个测试,我们只需要把scope改为prototype

       <bean id="student" class="com.springtest2.scope.Student" scope="prototype" />

再次打印结果

我在学英语。。。
null
false

3.使用注解定义 bean 的作用域

  1. 修改Student类。
  2. 修改xml文件,进行包扫描。
  3. 测试类不用变,直接执行,和之前运行结果医院一样。
@Component("student")
@Scope("prototype")
public class Student {
    private String study;

    public String getStudy() {
        return study;
    }

    public void setStudy(String study) {
        this.study = study;
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-4.2.xsd">

    <!--<bean id="student" class="com.springtest2.scope.Student" scope="singleton" />-->
    <!--<bean id="student" class="com.springtest2.scope.Student" scope="prototype" />-->
    <context:component-scan base-package="com.springtest2.scope" />
</beans>

注意
request,session和application这三个作用域都是基于web的Spring WebApplicationContext实现的,只有在web环境下(比如XmlWebApplicationContext)中才能使用。

如果开发者仅仅在常规的Spring IoC容器中比如ClassPathXmlApplicationContext在中使用这些作用域,那么将会抛出一个IllegalStateException来说明使用了未知的作用域。

4、请求作用域

<bean id="loginAction" class="com.foo.LoginAction" scope="request"/>

Spring容器会在每次用到loginAction来处理每个HTTP请求的时候都会创建一个新的LoginAction实例。也就是说,loginActionBean的作用域是HTTP Request级别的。 类似多例

5、会话作用域

<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>

每次创建UserPreferences也是一个全新的,类似多例

6、全局作用域

<bean id="appPreferences" class="com.foo.AppPreferences" scope="application"/>

Spring容器会在整个web应用范围使用到appPreferences的时候创建一个新的AppPreferences的实例。也就是说,appPreferencesBean是在ServletContext级别的,作为常规的ServletContext属性类似单例,但是也有如下不同之处:

  1. application作用域是每个ServletContext中包含一个,而不是每个SpringApplicationContext之中包含一个(某些应用中可能包含不止一个ApplicationContext)。

  2. application作用域仅仅作为ServletContext的属性可见,单例Bean是ApplicationContext可见。

参考:Spring Bean的作用域

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值