使用 ServletContext 加载 Applicationscoped Bean

Hau*_*uke 2 java jsf jboss servlets

我创建了一个类 StartupListener 实现 ServletContextListener。里面

@Override
public void contextInitialized(ServletContextEvent contextEvent) {
Run Code Online (Sandbox Code Playgroud)

我创建了一个计时器,每 30 秒执行一次。在这个计时器内,我想从我的 @ApplicationScoped - Bean 设置一个参数,以便将计时器中的信息显示到我的网站。

这是我到目前为止所做的:

启动监听器.java

package de.whatever;

import java.util.Timer;
import javax.naming.Context;

public class CargoServiceStartupListener implements ServletContextListener {

@Override
public void contextInitialized(ServletContextEvent contextEvent) {

    ....        

        ModuleScannerTask task = new ModuleScannerTask(contextEvent.getServletContext());
        Timer timer = new Timer("Scanner");
        timer.schedule(task, 0, 10000);
Run Code Online (Sandbox Code Playgroud)

ModuleScannerTask.java

package de.whatever;

import java.util.Enumeration;

public class ModuleScannerTask extends TimerTask{

private ServletContext context;

public ModuleScannerTask (ServletContext context) {
    this.context = context;
}

@Override
public void run() {
      System.out.println("Start scanning ...");
          ...
Run Code Online (Sandbox Code Playgroud)

ModuleBean.java

package de.whatever;

@ManagedBean (name="modOverview")
@ApplicationScoped
public class ModuleOverviewBean {

private String randomData;
Run Code Online (Sandbox Code Playgroud)

我的问题是如何将数据设置到我的应用程序 bean 中的randomData字段中。

我读到我可以从 ServletContext 加载属性“modOverview”,但返回 null。

加载和设置值的正确方法是什么?

我正在使用 JBoss(没有 spring)。

谢谢豪克

Bal*_*usC 5

如果它返回null,则仅意味着 JSF 尚未创建它。自己创建一个即可。当它已经存在于应用程序范围中时,JSF 不会覆盖它。您只需注意该类的任何托管属性都不会自动设置。

ModuleOverviewBean bean = (ModuleOverviewBean) servletContext.getAttribute("modOverview");

if (bean == null) {
    bean = new ModuleOverviewBean();
    servletContext.setAttribute("modOverview", bean);
}

// ...
Run Code Online (Sandbox Code Playgroud)

与该问题无关java.util.Timer,这是在 Java EE 应用程序中执行后台作业的一种非常糟糕的方法。至少看看ScheduledExecutorService,或者因为您已经在使用 JBoss,一个@Singleton带有方法的 EJB @Schedule

也可以看看:


更新:如果托管属性的设置也是您关心的问题,您还可以尝试按如下方式注释托管 bean,eager=true以便 JSF 将在 web 应用程序启动时自动创建它:

@ManagedBean(name="modOverview", eager=true)
Run Code Online (Sandbox Code Playgroud)

我只是不完全确定这是否会在你ServletContextListener跑步之前运行。我想会的。但是,如果您将@SingletonEJB 与@Schedule.