前言: 最近没事在浏览Spring官网,简单写一些相关的笔记 

       Spring可以用来指Spring Framework项目本身,它就是从这里开始的。随着时间的推移,其他Spring项目都建立在Spring框架之上。通常,当人们说Spring时,他们指的是整个Spring框架本身。

        Spring Framework框架提供了一种思想,当创建bean定义时,需要先创建一个配方(官网叫recipe),用配方创建由该bean定义定义出的类的实际实例。这种方式不仅可以实现控制要插入到从特定bean定义创建的对象中的依赖项和配置值,而且还可以控制从特定bean定义创建对象的范围。这种方法功能强大且灵活,因为您可以通过配置选择创建的对象的范围,而不必在Java类级别控制对象的范围。

       

1.BeanScope作用域

 Spring Framework支持六个作用域,其中request、session、application、websocket作用域仅在使用web感知的ApplicationContext时可用。

singleton(默认)

将单个bean定义范围限定为每个Spring IoC容器的单个对象实例

prototype

将单个bean定义范围扩展到任意数量的对象实例

request

将单个bean定义限定为单个HTTP请求的生命周期。也就是说,每个HTTP请求都有自己的bean实例

session

将单个bean定义范围限定到HTTP会话的生命周期

application

将单个bean定义范围限定到ServletContext的生命周期

websocket

将单个bean定义范围扩展到WebSocket的生命周期

1.1 singleton 作用域

单例作用域是Spring中的默认作用域,标签scope="singleton" 表示作用域是单例,一个单例bean只有一个共享实例被管理,对具有一个或多个与该bean定义匹配的ID的bean的所有请求都会导致Spring容器返回一个特定的bean实例。

<bean id="accountService" 
    class="com.something.DefaultAccountService" scope="singleton"/>

<!-- singleton 为默认范围也可以省略-->
<bean id="accountService" 
    class="com.something.DefaultAccountService"/>

单例作用域的工作方式很简单,当定义一个bean并将scope标签设置为单例时,Spring IoC容器创建好该bean定义定义的对象的一个实例后,这个实例存储在单例bean的缓存中。所有后续请求和引用都会返回缓存中的这个对象。下图显示了单例作用域的工作方式

spring 作用域 spring作用域最大的_作用域

Spring的单例bean概念不同于设计模式书中定义的单例模式。GoF单例硬编码定义对象的范围,以便每个ClassLoader创建一个且只有一个特定类的实例。Spring单例的范围最好描述为每个容器和每个bean。这意味着,如果在单个Spring容器中为特定类定义一个bean,那么Spring容器将创建该bean定义的类的一个且仅一个实例。 

1.2 prototype作用域

Bean作用域设置为原型prototype时,每次请求特定bean时创建一个新的bean实例。

<bean id="accountService" 
    class="com.something.DefaultAccountService" scope="prototype"/>

当使用具有原型bean依赖关系的单例作用域bean时,请注意依赖关系是在实例化时解决的。如果依赖项将原型作用域的bean注入到单例作用域的bean中,则会实例化一个新的原型bean,然后将依赖项注入到单实例bean中。原型实例是提供给单例作用域bean的唯一实例。下图显示了单例作用域的工作方式

spring 作用域 spring作用域最大的_jvm_02

应该对所有有状态bean使用原型prototype作用域,对无状态bean则使用单例作用域,比如数据访问对象(DAO)通常不配置为原型,因为典型的DAO不包含任何会话状态

1.3 Request作用域

只有在使用web感知的Spring ApplicationContext实现(例如XmlWebApplicationContext)时,请求request、会话session、应用程序application和websocket范围才可用。如果将这些作用域与常规的Spring IoC容器(如ClassPathXmlApplicationContext)一起使用,则会抛出一个IllegalStateException

Spring容器通过为每个HTTP请求使用LoginAction bean定义来创建一个新的LoginAction bean实例,如下XML定义。 loginAction bean的作用域是HTTP请求级别

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

当使用注释驱动的组件或Java配置时,@RequestScope注释可用于将组件分配给请求(Request)作用域范围

@RequestScope
@Component
public class LoginAction {
    // ...
}

1.4 Session作用域

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

定义一个名称为userPreferences 的Bean对象,Spring容器通过在单个HTTP会话的生存期内使用UserPreferences bean定义来创建UserPreferencesbean的新实例。userPreferencesbean的作用域实际上是HTTP会话级别,当HTTP会话最终被丢弃时,作用域为该特定HTTP会话的bean也被丢弃

使用注释驱动组件或Java配置时,可以使用@SessionScope注释将组件分配给会话(Session)作用域范围。

@SessionScope
@Component
public class UserPreferences {
    // ...
}

1.5 Application作用域

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

Spring容器通过对整个web应用程序使用AppPreferences bean定义一次来创建AppPreferencesbean的新实例。也就是说,appPreferences bean的作用域是ServletContext级别,并存储为常规的ServletContext属性。这有点类似于Spring单例bean,但在两个重要方面有所不同:它是每个ServletContext的单例,而不是每个Spring ApplicationContext

使用注释驱动组件或Java配置时,可以使用@SessionScope注释将组件分配给会话(Application)作用域范围。

@ApplicationScope
@Component
public class AppPreferences {
    // ...
}

1.6 WebSocket作用域

WebSocket作用域与WebSockets会话的生命周期相关联,并应用于WebSocket上的STOMP应用程序