【问题标题】:Spring Boot: Unable to access the request scope bean in Spring SchedulerSpring Boot:无法访问 Spring Scheduler 中的请求范围 bean
【发布时间】:2021-05-06 17:04:03
【问题描述】:

在我的 Spring Boot 应用程序中,我有一个每隔一小时执行一次的调度程序任务。在尝试访问请求范围 bean 的调度程序方法中。总是得到异常 org.springframework.beans.factory.BeanCreationException。

这是代码示例。

@Data
public class TestVo {
  private String message = "Hello";
}

@Bean
@Scope(value="request", proxyMode=ScopedProxyMode.TARGET_CLASS)
public TestVo testVo() {
    return new TestVo();
}

如下在调度器方法中访问上面创建的bean,

@Autowired
private TestVo testVo;

@Scheduled(cron="0 0 * * * *")
public void greetings() {
  System.out.println(testVo.getMessage()); // accessing request scope bean
}

使用上面的代码得到以下异常,

org.springframework.beans.factory.BeanCreationException: 错误 创建名为“scopedTarget.scheduledJobTaskExecutor”的bean:范围 'request' 对当前线程无效;考虑定义一个 如果您打算从 单身人士;嵌套异常是 java.lang.IllegalStateException: No 找到线程绑定请求:您指的是请求属性吗 在实际 Web 请求之外,或在 最初的接收线程?如果您实际上是在 一个网络请求,仍然收到此消息,您的代码可能是 在 DispatcherServlet 之外运行:在这种情况下,使用 RequestContextListener 或 RequestContextFilter 暴露当前 请求。

会有帮助..谢谢。

【问题讨论】:

    标签: java spring spring-boot taskscheduler requestscope


    【解决方案1】:

    请求范围的 bean 绑定到特定请求。每次请求到来时,都会创建一个新实例,并在请求完成后将其销毁。请求绑定到一个线程并使用该线程来处理请求(在非反应环境中)。即使有可能,调度程序也不知道在这种情况下应该使用哪个请求对象。假设您在计划作业开始运行时有 100 个活动请求,应该如何选择一个?或者如果没有任何活动请求(所以上下文没有实例?)。您可以通过代理将请求范围注入单例,因为单例方法调用将在同一个请求线程上处理,但计划作业使用其自己的线程池,该线程池不受任何请求的限制。 也许现在您可以在调度程序中使用请求范围的 bean 看到问题。 如果您想在调度程序和请求范围的 bean 中使用相同的逻辑,例如可以将其提取到超类中。

    【讨论】:

    • 感谢您的回复。请提供任何代码示例或参考资料,这样会更容易
    • 去掉范围注解就可以了。
    猜你喜欢
    • 1970-01-01
    • 2013-01-21
    • 2011-08-15
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-25
    相关资源
    最近更新 更多