一.  Scope属性类型

主要有以下六种:

① singleton(单例模式)- 默认值
  • 含义:在整个 Spring IoC 容器中,只存在一个该 Bean 的实例。

  • 生命周期:容器启动时创建(如果设置为懒加载则在第一次获取时创建),容器关闭时销毁。

  • 共享方式:所有对该 Bean 的依赖注入和查找,返回的都是同一个对象

  • 适用场景:无状态的 Bean,例如 Service、DAO、工具类等。这是最常用、最高效的作用域

② prototype(原型模式)
  • 含义:每次从容器中获取该 Bean 时,都会创建一个新的实例

  • 生命周期:每次获取时创建,实例返回给调用者后,其生命周期就由调用者管理,Spring 容器不再跟踪它的后续生命周期,也不会调用它的销毁方法。

  • 共享方式:每次获取到的都是不同的新对象

  • 适用场景:有状态的 Bean,每次使用都需要一个全新的、独立的对象,以避免线程安全问题。

③ request
  • 含义:为每一个 HTTP 请求创建一个新的 Bean 实例。

  • 生命周期:在一次 HTTP 请求开始时创建,请求结束时销毁。

  • 共享方式:在一次请求内部,所有注入的地方共享同一个实例。

  • 适用场景:用于存储请求相关的数据,如表单数据、请求属性等。

④ session
  • 含义:为每一个 HTTP Session 创建一个新的 Bean 实例。

  • 生命周期:在一个 HTTP Session 创建时创建,Session 失效时销毁。

  • 共享方式:在同一个用户会话内部,所有注入的地方共享同一个实例。

  • 适用场景:用于存储用户会话信息,如用户登录信息、购物车等。

⑤ application
  • 含义:为整个 Web 应用创建一个 Bean 实例。注意:它和 singleton 很像,但区别在于:

    • singleton 是每个 Spring 容器 一个实例(一个应用可以有多个容器)。

    • application 是每个 ServletContext 一个实例(一个应用通常只有一个)。

  • 生命周期:Web 应用启动时创建,应用停止时销毁。

  • 适用场景:用于存储全局的、应用级别的数据,其生命周期与 ServletContext 相同。

⑥ websocket
  • 含义:为每一个 WebSocket 会话创建一个 Bean 实例。

  • 生命周期:在 WebSocket 会话建立时创建,会话关闭时销毁。

  • 适用场景:用于存储与单个 WebSocket 连接相关的状态信息。

二.单例Bean注入其它scope的场景

1.类的准备

package com.example.springdemo.demos.a26;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;

/**
 * @author zhou
 * @version 1.0
 * @description TODO
 * @date 2025/10/14 22:17
 */
@Scope("application")
@Component
public class BeanForApplication {
    private static final Logger log = LoggerFactory.getLogger(BeanForApplication.class);
    @PreDestroy
    public void destroy(){
        log.info("destroy");
    }
}
package com.example.springdemo.demos.a26;

import com.example.springdemo.demos.a25.Bean1;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;

/**
 * @author zhou
 * @version 1.0
 * @description TODO
 * @date 2025/10/14 22:13
 */
@Scope("request")
@Component
public class BeanForRequest {
    private static final Logger log = LoggerFactory.getLogger(BeanForRequest.class);
    @PreDestroy
    public void destroy(){
        log.info("destroy");
    }
}
package com.example.springdemo.demos.a26;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;

/**
 * @author zhou
 * @version 1.0
 * @description TODO
 * @date 2025/10/14 22:15
 */
@Scope("session")
@Component
public class BeanForSession {
    private static final Logger log = LoggerFactory.getLogger(BeanForSession.class);
    @PreDestroy
    public void destroy(){
        log.info("destroy");
    }
}

2.MyController

package com.example.springdemo.demos.a26;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @author zhou
 * @version 1.0
 * @description TODO
 * @date 2025/10/14 22:18
 */
@RestController
public class MyController {
    @Lazy
    @Autowired
    private BeanForRequest beanForRequest;

    @Lazy
    @Autowired
    private BeanForSession beanForSession;

    @Lazy
    @Autowired
    private BeanForApplication beanForApplication;

    @GetMapping(value = "/test", produces = "text/html")
    public String test(HttpServletRequest request, HttpSession session) {
        ServletContext sc = request.getServletContext();
        String sb = "<ul>" +
                "<li>" + "request scope:" + beanForRequest + "</li>" +
                "<li>" + "session scope:" + beanForSession + "</li>" +
                "<li>" + "application scope:" + beanForApplication + "</li>" +
                "</ul>";
        return sb;
    }


}

        在单例Bean中注入其它Scope的Bean,必须配置@Lazy注解注入。

3.启动类

package com.example.springdemo.demos.a26;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author zhou
 * @version 1.0
 * @description TODO
 * @date 2025/10/14 22:12
 */
@SpringBootApplication
public class b07Application {
    public static void main(String[] args) {

        SpringApplication.run(b07Application.class,args);
    }
}

4.访问接口

1)刷新浏览器

             BeanForRequest对象变了,其它两个对象没有变。

2)换一个浏览器

       BeanForSession和BeanForRequest对象都改变了,只有BeanForApplication对象没有改变。

3)关闭容器

       BeanForSession和BeanForRequest对象都被销毁并输出在控制台,但BeanForApplication的日志并没有打印。BeanForApplication在整个ServletContext容器运行期间都不会变。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐