You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot单例@Component中如何使用Request Scope对象?

解决单例组件中使用请求作用域对象的问题

你不需要在所有方法里传递参数,Spring提供了两种常用方案来实现单例组件中安全使用请求作用域的对象:

方案一:创建请求作用域的持有类(推荐)

创建一个专门的请求作用域bean来持有myObject,Spring会自动为这个bean生成代理,确保单例组件每次调用都能获取当前请求的实例。

步骤1:定义请求作用域的持有类

import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;

@Component
@Scope(
    value = WebApplicationContext.SCOPE_REQUEST,
    proxyMode = ScopedProxyMode.TARGET_CLASS
)
public class MyRequestScopedHolder {
    private MyClass myObject;

    public MyClass getMyObject() {
        return myObject;
    }

    public void setMyObject(MyClass myObject) {
        this.myObject = myObject;
    }
}

步骤2:修改单例组件注入持有类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyComponent {
    @Autowired
    private MyBC myBC;
    @Autowired
    private MyRequestScopedHolder requestHolder;

    public void method1(MyClass param) {
        requestHolder.setMyObject(param);
        method2();
    }

    public void method2() {
        System.out.println(requestHolder.getMyObject());
    }
}

说明:proxyMode = ScopedProxyMode.TARGET_CLASS是关键,Spring会生成CGLIB代理类,单例的MyComponent注入的是代理对象,每次调用requestHolder的方法时,代理会从当前请求上下文获取真实的持有类实例,保证每个请求的myObject相互独立。

方案二:使用RequestContextHolder直接操作请求属性

如果不想额外创建类,可以借助Spring的RequestContextHolder直接把对象存在请求作用域中:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

@Component
public class MyComponent {
    @Autowired
    private MyBC myBC;

    public void method1(MyClass param) {
        // 将对象存入当前请求属性
        RequestContextHolder.getRequestAttributes()
            .setAttribute("myObject", param, RequestAttributes.SCOPE_REQUEST);
        method2();
    }

    public void method2() {
        // 从当前请求属性中取出对象
        MyClass myObject = (MyClass) RequestContextHolder.getRequestAttributes()
            .getAttribute("myObject", RequestAttributes.SCOPE_REQUEST);
        System.out.println(myObject);
    }
}

说明:RequestContextHolder会绑定当前线程的请求上下文,所以并发场景下每个请求的属性互不干扰,但这种方式代码耦合Spring API,适合简单场景。

内容的提问来源于stack exchange,提问作者tpcordeiro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 03:01:00