Spring Bean Scopes – @Scope 注解

创建bean意味着,您创建类的实际实例,并根据bean定义注入依赖项。Bean 定义就像一个配方,您可以使用相同的配方创建该类的多个实例。 Scope 控制需要创建的实例数量和 bean 的生命周期。
Spring Framework 支持六个Scope,此外,您还可以创建自定义Scope。
1、单例scope —— @Scope("singleton") ——bean 的默认Scope。
2、原型scope——@Scope("prototype")——你每次都会得到一个类的新对象实例。
3、Request scope——@RequestScope——为每个单独的 Http 请求创建一个对象实例。
4、Session scope——@SessionScope——将单个 bean 定义的范围限定为 Http 会话的生命周期。
5、Application scope —— @ApplicationScope - 将单个 bean定义限定为ServletContext 的生命周期。
6、WebSocket scope – @Scope("websocket") – 将单个 bean 定义限定为 WebSocket 的生命周期。
7、自定义scope - Spring 还允许您创建自定义scope bean。
Singleton bean 作用域——@Scope(“singleton”)
当您将 bean 定义为 Singleton 范围时,Spring IoC 会根据 bean 定义精确地创建对象的一个实例。这个单例实例存储在缓存中,spring IoC 为同一个 bean 的所有后续请求和引用返回这个存储的实例。
简单来说,假设我将 itemDao 声明为单例 bean。无论我尝试在多少地方获取这个 DAO bean,Spring 都只会创建这个 bean 的一个实例,并在我使用的任何地方注入相同的实例。
请记住:Singleton 是 Spring IoC 中的默认 bean 范围。
当然,有几种方法可以声明 bean 范围。我们将使用@Scope 注释。 使用 Singleton 范围定义 ItemDao bean。
@Configuration
public class BasicIocConfig {
@Bean
@Scope("singleton")
public ItemDao itemDao() {
return new ItemDao();
}
}
您还可以重写@Scope,如下所示
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
您可以将@Scope 注释与@Component、@Repository 或@Service 注释一起使用。
@Scope("singleton")
@Component
public class ItemDao {
public void doSomething(){ //... }
}
在 XML 配置中,您可以设置scope如下。
<?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="itemDao" scope="singleton" class="basic.ioc.demo.ItemDao"/>
</beans>
Prototype bean 作用域——@Scope(“prototype”)
这个作用域与 Singleton 正好相反。每次您请求 bean 时,Spring IoC 都会创建一个新 bean。
注意:您应该始终为所有有状态的 bean 使用原型scope,例如 pojo、命令对象、模型对象等。 并对 DAO、服务、控制器等无状态 bean 使用单例scope。
就像单例一样,原型scope也可以定义如下。
@Configuration
public class BasicIocConfig {
@Bean
@Scope("prototype")
public Item item() {
return new Item();
}
使用以下方法优化字符串池并避免拼写错误。
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
或者,如果您使用 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.xsd">
<bean id="item" scope="prototype" class="basic.ioc.constructor.xml.Item"/>
</beans>
Request scope spring bean – @RequestScope
request、session、application和 websocket scope在 Spring web-aware ApplicationContext 中可用。简单来说,这些范围仅在 Spring Web 应用程序中可用。在使用它们之前,请确保您已经完成了正确的 web-app/web MVC 配置。
请求范围为每个 Http 请求创建一个新的 bean 实例。
与其他范围类似,如果您使用带注释的 java 配置,请使用 RequestScope 注释。
@RequestScope
@Component
public class LoginRequestAction {
// ...
}
同样,如果您使用的是纯 XML 配置
<bean id="loginRequestAction" class="com.something.LoginRequestAction" scope="request"/>
Session scope bean – @SessionScope
在session scope的 bean 中,spring Ioc 为整个 Http Session 创建 bean 的一个实例。用户偏好、购物车等数据配置为会话范围是有意义的。
同样,如果您使用 XML 配置
<bean id="shoppingCart" class="com.shopping.ShoppingCart" scope="session"/>
Application scope bean – @ApplicationScope
application scope的 bean 的范围在 ServletContext 级别,并存储为常规 ServletContext 属性。pplication scope bean 可能听起来像singleton scope bean,但在两个重要方面有所不同。
1、应用程序范围的 bean 是每个 ServletContext 的单例,而不是每个 ApplicationContext。
2、它作为 ServletContext 属性公开和可见。
可以使用注释或基于 XML 的配置来完成,如下所示,
@ApplicationScope
@Component
public class AppThemePreferences {
// ...
}
<bean id="appThemePreferences" class="com.global.AppThemePreferences" scope="application"/>
WebSocket scope bean – @Scope(“websocket”)
WebSocket 范围的 bean 存储在 WebSocket 会话属性中。每当在整个 WebSocket 会话期间引用 bean 时,都会返回相同的 bean 实例。
@Scope("websocket")
@Component
public class UpdateNotifier {
//do tasks
}
大多数情况下,我们将在我们的应用程序中使用原型和单例scope。