【spring】@Scope注解学习

@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实例的生命周期和作用域。以下是一些常见的使用场景:

  1. 单例模式(Singleton):这是默认的作用域。在整个应用中,只会创建一个Bean实例,所有的依赖注入都将使用这个实例。适用于无状态的Bean,例如Service层的Bean。

    java 复制代码
    @Service
    public class SingletonService {
        // ...
    }
  2. 原型模式(Prototype):每次请求(例如通过Controller的getBean()方法)都会创建一个新的Bean实例。适用于有状态的Bean,例如DAO层的Bean,因为每次请求都需要一个新的实例来处理请求。

    java 复制代码
    @Repository
    @Scope("prototype")
    public class PrototypeDao {
        // ...
    }
    复制代码
  3. 请求作用域(Request):在Web应用中,为每个HTTP请求创建一个新的Bean实例。适用于需要在请求之间保持状态的Bean,例如在处理用户会话数据时。

    java 复制代码
    @Component
    @Scope("request")
    public class RequestScopedComponent {
        // ...
    }
  4. 会话作用域(Session):在Web应用中,为每个HTTP Session创建一个新的Bean实例。适用于需要跨多个请求保持状态的Bean,例如购物车数据。

    java 复制代码
    @Component
    @Scope("session")
    public class SessionScopedComponent {
        // ...
    }
    复制代码
  5. 应用作用域(Application):在Web应用中,为每个Web应用程序创建一个Bean实例。适用于需要在整个应用程序中共享的数据,例如应用程序配置。

    java 复制代码
    @Component
    @Scope("application")
    public class ApplicationScopedComponent {
        // ...
    }
    复制代码
  6. 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 ();
    }
}
运行结果



相关推荐
暮湫16 分钟前
泛型(2)
java
南宫生26 分钟前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石34 分钟前
12/21java基础
java
李小白6642 分钟前
Spring MVC(上)
java·spring·mvc
sanguine__42 分钟前
Web APIs学习 (操作DOM BOM)
学习
GoodStudyAndDayDayUp1 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea
装不满的克莱因瓶1 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb
n北斗2 小时前
常用类晨考day15
java
骇客野人2 小时前
【JAVA】JAVA接口公共返回体ResponseData封装
java·开发语言
yuanbenshidiaos3 小时前
c++---------数据类型
java·jvm·c++