【问题标题】:Access ApplicationScoped bean through ServletContext通过 ServletContext 访问 ApplicationScoped bean
【发布时间】:2015-01-26 16:42:15
【问题描述】:

我有一个 ApplicationScoped bean,我想在石英作业实现中访问它。 该 bean 通过运行时保存一个哈希图,我想在作业运行时填充哈希图。 但是,FacesContext 与作业内部的上下文无关。 我可以访问 ServletContext。是否可以通过 ServletContext 访问我的 bean?

我的访问 Servlet 上下文的代码:

@Override
public void execute(JobExecutionContext context) throws JobExecutionException {

    SchedulerContext schedulerContext=null;
    try {
        schedulerContext=context.getScheduler().getContext();
    }
    catch (SchedulerException e) {
        e.printStackTrace();
    }

    ServletContext servletContext=(ServletContext)schedulerContext.get("QuartzServletContext");
    BOCacheM bOCacheM = (BOCacheM) servletContext.getAttribute("bOCacheM");
}

我的 QuartzServletContext 在 web.xml 中定义为:

<context-param>
    <param-name>quartz:scheduler-context-servlet-context-key</param-name>
    <param-value>QuartzServletContext</param-value>
</context-param>

<listener>
    <listener-class>
        org.quartz.ee.servlet.QuartzInitializerListener
    </listener-class>
</listener>

【问题讨论】:

  • Quartz Scheduler 和那些东西使用它们自己的线程来运行。看起来像一些设计问题。答案完全取决于问题中不可见的功能要求。

标签: jsf quartz-scheduler


【解决方案1】:

是的,它作为属性存储在ServletContext 中。像任何其他属性一样获取它:

YourApplicationScopedBean bean = servletContext.getAttribute("yourApplicationScopedBeanName");
//use it...

如果beannull,那么看起来你的bean 在石英作业开始时没有创建。确保通过将 eager=true 添加到其定义来创建 bean:

@ManagedBean(eager=true)
@ApplicationScoped
public class YourApplicationScopedBean {
    //...

    @PostConstruct
    public void init() {
        //initialize your shared resources here...
    }
}

请注意,eager=true 仅适用于 @ApplicationScoped bean。

如果这仍然不起作用,那么即使在创建 bean 并将其存储在应用程序上下文中之前,您的石英作业似乎就已被触发。最好在 ServletContextListener 而不是 @ApplicationScoped bean 中初始化此资源,并通过另一个组件提供对该资源的访问。

【讨论】:

  • 奇怪的是,eager=true 似乎不起作用。作业运行时不会实例化 bean。通过调试,我看到了 servletContext 属性,而我的 bean 不是其中的一部分。也许我弄错了 servletContext。
  • 我建议您在实现 ServletContextListener#initialize 的类中创建此 Map,而不是在应用程序范围的 bean 或缓存库之类的第三个元素中(Infinispan、EhCache,无论您喜欢什么) .请注意,quartz 不会触发 HTTP 请求,因此您的quartz 作业访问任何 Web 组件是一个糟糕的设计,例如ServletContext, HttpServletSession, Servlet 一般...
  • 如果工作是我访问哈希的唯一方式,我认为您的建议是正确的。但是,我有一个 xhtml 文件,其中列出了哈希映射,并且我有一个更新哈希的按钮,所以我有点需要它在一个 bean 中。不过,我感谢您的帮助。
  • @Rita 您可以从您的石英作业中使用它,并让您的托管 bean 更改它。在 bean 中执行更改会产生额外的成本(例如 10 到 50 毫秒),因为现在他们必须访问此资源,而不是直接访问 ServletContext,但这并不难。
  • 我试图弄清楚为什么我在 servletContext 中找不到 bean。我是否有可能以错误的方式访问我的 ServletContext?
猜你喜欢
  • 1970-01-01
  • 2016-06-08
  • 2019-11-28
  • 2015-02-21
  • 1970-01-01
  • 2012-12-23
  • 2015-03-10
  • 2016-02-11
相关资源
最近更新 更多