Spring Boot:无法访问 Spring Scheduler

问题描述

在我的 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 来公开当前 请求。

会有所帮助...谢谢。

解决方法

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...