@Scope介绍
@Scope
注解是Spring框架中用于指定bean作用域的注解。在Spring中,一个bean的作用域定义了该bean的生命周期和创建bean实例的上下文。Spring提供了几种预定义的作用域,同时也支持自定义作用域。通过使用@Scope
注解,开发者可以更精确地控制Spring容器如何创建和维护bean实例。
@Scope源码
java
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {
@AliasFor("scopeName")
String value() default "";
@AliasFor("value")
String scopeName() default "";
ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
}
源代码截图
@Scope属性介绍
-
value:表示作用域,可以取如下值。
-
singleton:这是默认的作用域。在singleton作用域下,无论多少次请求,Spring容器都会为每个bean定义创建一个实例。这个实例在容器的生命周期内是唯一的,所有请求都会共享这个实例。
-
prototype:在prototype作用域下,每次请求或者注入bean时,Spring容器都会创建一个新的bean实例。这意味着每个bean的实例都是独立的,它们之间没有共享状态。
-
request:这个作用域与HTTP请求相关联。在request作用域下,每个HTTP请求都会创建一个新的bean实例。这个bean实例仅在当前请求内有效,请求结束后,该实例就会被销毁。
-
session:与HTTP会话相关。在session作用域下,bean的实例将与用户的HTTP会话绑定。不同的用户会话将会创建不同的bean实例。
-
application:这个作用域与整个web应用的生命周期相关。在application作用域下,bean的实例在所有用户和请求之间共享,并且只在应用的生命周期内有效。
-
websocket:与WebSocket会话相关。在websocket作用域下,每个WebSocket会话都会创建一个新的bean实例。
-
-
scopeName:Spring4.2版本开始新增的属性,作用与value属性相同。
-
proxyMode:指定Bean对象使用的代理方式,可以取如下值。
- DEFAULT:默认值,作用与NO相同。
- NO:不使用代理。
- INTERFACES:使用JDK基于接口的代理。
- TARGET_CLASS:使用CGLIB基于目标类的子类创建代理对象。
@Scope注解使用场景
@Scope
注解在Spring框架中用于指定Bean实例的生命周期和作用域。以下是一些常见的使用场景:
-
单例模式(Singleton):这是默认的作用域。在整个应用中,只会创建一个Bean实例,所有的依赖注入都将使用这个实例。适用于无状态的Bean,例如Service层的Bean。
java@Service public class SingletonService { // ... }
-
原型模式(Prototype):每次请求(例如通过Controller的getBean()方法)都会创建一个新的Bean实例。适用于有状态的Bean,例如DAO层的Bean,因为每次请求都需要一个新的实例来处理请求。
java@Repository @Scope("prototype") public class PrototypeDao { // ... }
-
请求作用域(Request):在Web应用中,为每个HTTP请求创建一个新的Bean实例。适用于需要在请求之间保持状态的Bean,例如在处理用户会话数据时。
java@Component @Scope("request") public class RequestScopedComponent { // ... }
-
会话作用域(Session):在Web应用中,为每个HTTP Session创建一个新的Bean实例。适用于需要跨多个请求保持状态的Bean,例如购物车数据。
java@Component @Scope("session") public class SessionScopedComponent { // ... }
-
应用作用域(Application):在Web应用中,为每个Web应用程序创建一个Bean实例。适用于需要在整个应用程序中共享的数据,例如应用程序配置。
java@Component @Scope("application") public class ApplicationScopedComponent { // ... }
-
WebSocket作用域(WebSocket):在Web应用中,为每个WebSocket会话创建一个Bean实例。适用于需要在WebSocket会话中保持状态的Bean,例如聊天应用中的用户状态。
java@Component @Scope("websocket") public class WebSocketScopedComponent { // ... }
@Scope测试示例代码
示例代码 一
ScopePrototypeDemo类
java
package com.yang.SpringTest.annotation.scopeLearn;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
/**
* <p>ScopePrototypeDemo类</p>
*
* @author By: chengxuyuanshitang
* Package com.yang.SpringTest.annotation.scopeLearn
* Ceate Time 2024-04-09 17:04
*/
@Data
@Slf4j
public class ScopePrototypeDemo {
public ScopePrototypeDemo () {
log.info ("------ ScopePrototypeDemo init -----");
}
}
ScopeSingletonDemo类
java
package com.yang.SpringTest.annotation.scopeLearn;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
/**
* <p>ScopeSingletonDemo类</p>
*
* @author By: chengxuyuanshitang
* Package com.yang.SpringTest.annotation.scopeLearn
* Ceate Time 2024-04-09 17:04
*/
@Data
@Slf4j
public class ScopeSingletonDemo {
public ScopeSingletonDemo () {
log.info ("------ ScopeSingletonDemo init -----");
}
}
ScopeDemoConfig配置类
java
package com.yang.SpringTest.annotation.scopeLearn;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
/**
* <p>ScopeDemoConfig配置类</p>
*
* @author By: chengxuyuanshitang
* Package com.yang.SpringTest.annotation.scopeLearn
* Ceate Time 2024-04-09 17:08
*/
@Configuration
@ComponentScan(value = {"com.yang.SpringTest.annotation.scopeLearn"})
public class ScopeDemoConfig {
@Bean
@Scope(value = "singleton")
public ScopePrototypeDemo scopePrototypeDemo () {
return new ScopePrototypeDemo ();
}
@Bean
@Scope(value = "prototype")
public ScopeSingletonDemo scopeSingletonDemo () {
return new ScopeSingletonDemo ();
}
}
ScopeDemoTest 测试类
java
package com.yang.SpringTest.annotation.scopeLearn;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* <p>ScopeDemoTest 测试类</p>
*
* @author By: chengxuyuanshitang
* Package com.yang.SpringTest.annotation.scopeLearn
* Ceate Time 2024-04-09 17:10
*/
@Slf4j
public class ScopeDemoTest {
public static void main (String[] args) {
log.info ("========== 创建IOC容器开始==========");
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext (ScopeDemoConfig.class);
log.info ("==========创建IOC容器结束==========");
log.info ("==========IOC容器中获取Bean开始==========");
ScopeSingletonDemo scopeSingletonDemo1 = context.getBean (ScopeSingletonDemo.class);
ScopeSingletonDemo scopeSingletonDemo2 = context.getBean (ScopeSingletonDemo.class);
log.info ("**************** scopeSingletonDemo1是否等于scopeSingletonDemo2 : {}", (scopeSingletonDemo1 == scopeSingletonDemo2));
ScopePrototypeDemo scopePrototypeDemo1 = context.getBean (ScopePrototypeDemo.class);
ScopePrototypeDemo scopePrototypeDemo2 = context.getBean (ScopePrototypeDemo.class);
log.info ("**************** scopePrototypeDemo1是否等于scopePrototypeDemo2 : {}", (scopePrototypeDemo1 == scopePrototypeDemo2));
log.info ("==========从IOC容器中获取Bean结束==========");
context.close ();
}
}