@Scope介绍
@Scope
注解是Spring框架中用于指定bean作用域的注解。在Spring中,一个bean的作用域定义了该bean的生命周期和创建bean实例的上下文。Spring提供了几种预定义的作用域,同时也支持自定义作用域。通过使用@Scope
注解,开发者可以更精确地控制Spring容器如何创建和维护bean实例。
@Scope源码
@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。
@Service public class SingletonService {// ... }
-
原型模式(Prototype):每次请求(例如通过Controller的getBean()方法)都会创建一个新的Bean实例。适用于有状态的Bean,例如DAO层的Bean,因为每次请求都需要一个新的实例来处理请求。
@Repository @Scope("prototype") public class PrototypeDao {// ... }
-
请求作用域(Request):在Web应用中,为每个HTTP请求创建一个新的Bean实例。适用于需要在请求之间保持状态的Bean,例如在处理用户会话数据时。
@Component @Scope("request") public class RequestScopedComponent {// ... }
-
会话作用域(Session):在Web应用中,为每个HTTP Session创建一个新的Bean实例。适用于需要跨多个请求保持状态的Bean,例如购物车数据。
@Component @Scope("session") public class SessionScopedComponent {// ... }
-
应用作用域(Application):在Web应用中,为每个Web应用程序创建一个Bean实例。适用于需要在整个应用程序中共享的数据,例如应用程序配置。
@Component @Scope("application") public class ApplicationScopedComponent {// ... }
-
WebSocket作用域(WebSocket):在Web应用中,为每个WebSocket会话创建一个Bean实例。适用于需要在WebSocket会话中保持状态的Bean,例如聊天应用中的用户状态。
@Component @Scope("websocket") public class WebSocketScopedComponent {// ... }
@Scope测试示例代码
示例代码 一
ScopePrototypeDemo类
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类
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配置类
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 测试类
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 ();}
}