【问题标题】:How to check for Request Scope availability in Spring?如何在 Spring 中检查请求范围的可用性?
【发布时间】:2015-06-05 12:22:17
【问题描述】:

我正在尝试设置一些代码,如果 spring 的请求范围可用,则以一种方式运行,如果所述范围不可用,则以另一种方式运行。

有问题的应用程序是一个 Web 应用程序,但有一些 JMX 触发器和计划任务(即 Quartz)也会触发调用。

例如

/**
 * This class is a spring-managed singleton
 */
@Named
class MySingletonBean{

    /**
     * This bean is always request scoped
     */
    @Inject
    private MyRequestScopedBean myRequestScopedBean; 

    /* can be invoked either as part of request handling
       or as part of a JMX trigger or scheduled task */
    public void someMethod(){
        if(/* check to see if request scope is available */){
            myRequestScopedBean.invoke();
        }else{
            //do something else
        }
    }
}

假设myRequestScopedBean 是请求范围内的。

我知道这可以通过 try-catch 围绕 myRequestScopedBean 的调用来完成,例如:

/**
 * This class is a spring-managed singleton
 */
@Named
class MySingletonBean{

    /**
     * This bean is always request scoped
     */
    @Inject
    private MyRequestScopedBean myRequestScopedBean; 

    /* can be invoked either as part of request handling
       or as part of a JMX trigger or scheduled task */
    public void someMethod(){
        try{
            myRequestScopedBean.invoke();
        }catch(Exception e){
            //do something else
        }
    }
}

但这看起来真的很笨重,所以我想知道是否有人知道一种优雅的 Spring 方式来询问某些东西以查看请求范围的 bean 是否可用。

非常感谢!

【问题讨论】:

  • 为什么需要检查 bean 是否是请求范围的?这似乎很倒退。
  • 抱歉,这可能不清楚。 bean 始终是请求范围的,但 someMethod 的调用可能不是请求处理的一部分
  • 我还是一头雾水。 MyRequestScopedBean 是请求范围的。 MySingletonBean 是单例范围的。您需要检查什么以及为什么?
  • 我试着澄清一下这个问题。我所追求的是请求范围的 bean 是否可用,使用它们,否则,回退到其他东西。我意识到这个问题有点含糊,但出于雇主 IP 的原因,我不能更具体。
  • 我不确定这是否准确。 Spring 似乎注入了一个单例代理,然后在调用请求范围的 bean 时将尝试从一些内部存储中检索它(我相信线程本地)。如果进入MySingletonBean 的线程是一个请求处理线程,那么一切都会正常工作,但如果该线程是作为 JMX 触发器的一部分触发的,那么你会从 spring 的内部得到一些异常。

标签: java spring spring-mvc spring-ioc


【解决方案1】:

您可以使用此处描述的 if 检查

SPRING - Get current scope

if (RequestContextHolder.getRequestAttributes() != null) 
    // request thread

而不是捕获异常。 有时这看起来是最简单的解决方案。

【讨论】:

    【解决方案2】:

    您可以注入Provider<MyRequestScopedBean> 并在调用get 方法时捕获异常,但您应该重新考虑您的设计。如果你对此有强烈的感觉,你可能应该有两个具有不同限定符的 bean

    编辑

    再想一想,如果您使用的是 java 配置,@Scope("prototype") 您的 @Bean 方法并在那里做出决定,您可以通过 RequestContextHolder 获取请求上下文的句柄(如果有)。但我强烈建议您重新考虑您的设计

    【讨论】:

    • 感谢您的回答。如果我理解正确,您建议将 try-catch 包装在 Provider 中?我试图弄清楚是否有某种方法可以查询这是否可行,而不是尝试并失败。不过感谢答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 2011-09-02
    相关资源
    最近更新 更多