Bootstrap

Spring 框架中 Bean 的 6 种作用域!

目录

1、singleton(单例模式)

2、prototype(原型模式)

3. request、session、application、websocket作用域


关注 JAVA学习课堂 微信公众号,获取更多学习笔记,。

Spring中,那些组成应用程序的主体由Spring IoC容器所管理的对象,被称之为bean。简单地讲,bean就是由IoC容器初始化、装配及管理的对象。

Spring Framework中,总共定义了6种bean 的作用域,其中有4种作用域只有当应用为web应用的时候才有效,并且Spring还支持自定义作用域。

1、singleton(单例模式)

如果一个bean的作用域为Singleton,那么Spring IoC容器中只会存在一个共享的bean实例。当获取bean时,只要id与该bean相匹配,就会返回同一bean的实例。Singleton是单例模式,就是在创建容器时就同时自动创建了一个bean的对象,不管你是否使用,它都已经存在了,且每次获取到的对象都是同一个对象。

注:上图中,有3个地方引用了这个bean,这3个引用指向的都是同一个bean实例。

singleton作用域是Spring中默认的作用域,可以在定义bean的时候指定或者不指定都可以,如下:

<!-- 不指定作用域,默认是singleton -->
<bean id="accountService" class="com.something.DefaultAccountService"/>
​
<!-- 显示指定作用域为singleton -->
<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>

测试:

<bean id="user" class="com.atangbiji.pojo.User" scope="singleton">
    <property name="name" value="zcm"/>
    <property name="age" value="18"/>
</bean>

import com.atangbiji.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
​
public class MyTest {
    @Test
    public void testDI3(){
        //userBeans.xml文件,IOC容器生成并管理相应的Bean对象
        ApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml");
        //通过Spring的上下文对象,从IOC容器中获取Bean对象
        User user1 = (User)context.getBean("user");
        User user2 = (User)context.getBean("user");
        //输出两个对象的HashCode,并判断两个对象是否相同
        System.out.println(user1.hashCode());
        System.out.println(user2.hashCode());
        System.out.println(user1 == user2);
    }
}

执行结果如下图所示:

可以发现:两次代码执行的hashCode 地址是相同的,可以证明,Spring IoC容器中只会存在一个共享的bean实例

2、prototype(原型模式)

prototype作用域表示的是一个bean定义可以创建多个bean实例,有点像一个类可以new多个实例一样。

也就是说,当注入到其他的bean中或者对这个bean定义调用getBean()时,都会生成一个新的bean实例。

prototype作用域表示的是一个bean定义可以创建多个bean实例,有点像一个类可以new多个实例一样。

也就是说,当注入到其他的bean中或者对这个bean定义调用getBean()时,都会生成一个新的bean实例。

prototype作用域的工作过程如图:

Prototype是原型模式,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。在XML中将bean定义成prototype,可以这样配置:

测试:

<bean id="user" class="com.atangbiji.pojo.User" scope="singleton">
    <property name="name" value="zcm"/>
<property name="age" value="18"/>
</bean>

重新运行测试代码后结果:

注:对有状态的bean应该使用prototype作用域;而对无状态的bean则应该使用singleton作用域。

3. request、session、application、websocket作用域

requestsessionapplicationwebsocket作用域只有在web环境下才有用。

3.1初始化web配置

为了支持requestsessionapplicationwebsocket作用域,在定义bean之前需要一些初始化配置。

如果你在Spring Web MVC中定义这4中作用域,不需要进行初始化配置,如果你使用的是Servlet 2.5web容器,这些容器不使用SpringDispatcherServlet,你需要注册org.springframework.web.context.request.RequestContextListener。对于Servlet 3.0+的web容器,可以通过编程的方式使用WebApplicationInitializer接口来完成,或者使用xml配置:

<web-app>
    ...
    <listener>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>
    ...
</web-app>

3.2 request作用域

下面的xml配置指定了bean的作用域为request

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

3.3 session作用域

xml中可以这样定义bean的作用域为session作用域:

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

Spring为每个HTTP Session创建一个新的UserPreferencesbean。每个bean之间是不可见的,只属于对应的Session,当Session销毁的时候,对应的bean也会被销毁

3.4  application作用域

xml中可以这样定义bean的作用域为application作用域:

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

Spring为整个web上下文创建一个AppPreferences 的bean。也就是说,这个bean作用域是在ServletContext级别,它是作为ServletContext的一个属性存在的。

 关注 JAVA学习课堂 微信公众号,获取更多学习笔记,。

;