1

在我的 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时出错:当前线程的范围“请求”无效;如果您打算从单例中引用它,请考虑为该 bean 定义一个作用域代理;嵌套异常是 java.lang.IllegalStateException:未找到线程绑定请求:您是指实际 Web 请求之外的请求属性,还是在原始接收线程之外处理请求?如果您实际上是在 Web 请求中操作并且仍然收到此消息,则您的代码可能在 DispatcherServlet 之外运行:在这种情况下,请使用 RequestContextListener 或 RequestContextFilter 来公开当前请求。

会有帮助的..谢谢。

4

1 回答 1

0

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

于 2021-05-06T17:24:46.943 回答