Java 使用ServletContext加载应用程序范围的Bean

Java 使用ServletContext加载应用程序范围的Bean,java,jsf,servlets,jboss,Java,Jsf,Servlets,Jboss,我创建了一个类StartupListener实现ServletContextListener。里面 @Override public void contextInitialized(ServletContextEvent contextEvent) { 我创建了一个计时器,每30秒执行一次。在这个计时器中,我想从@ApplicationScoped-Bean设置一个参数,以便将计时器中的信息显示到我的网站上 以下是我迄今为止所做的: StartupListener.java package d

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

@Override
public void contextInitialized(ServletContextEvent contextEvent) {
我创建了一个计时器,每30秒执行一次。在这个计时器中,我想从@ApplicationScoped-Bean设置一个参数,以便将计时器中的信息显示到我的网站上

以下是我迄今为止所做的:

StartupListener.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);
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 ...");
          ...
package de.whatever;

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

private String randomData;
ModuleScannerTask.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);
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 ...");
          ...
package de.whatever;

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

private String randomData;
ModuleBean.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);
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 ...");
          ...
package de.whatever;

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

private String randomData;
我的问题是如何在我的应用程序bean中将数据设置为randomData字段

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

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

我正在使用JBoss(没有spring)

谢谢
Hauke

如果它返回
null
,那么它只是意味着JSF还没有创建它。你自己做一个就行了。JSF在应用程序范围中已经存在时不会覆盖它。您只需注意,此类的任何托管属性都不会自动设置

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

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

// ...

与问题无关在JavaEE应用程序中,
java.util.Timer
是一种非常糟糕的后台工作方式。至少看一看,或者因为您已经在使用JBoss,一个带有方法的EJB

另见:

更新:如果托管属性的设置也是您关心的问题,您还可以尝试用
eager=true
注释托管bean,如下所示,以便JSF在webapp启动时自动创建它:

@ManagedBean(name="modOverview", eager=true)

我只是不完全确定这是否会在
ServletContextListener
运行之前运行。我想会的。但是,如果您使用带有
@Schedule

@Singleton
EJB,它肯定会起作用。谢谢您的帮助和信息。我会仔细看看。但是豆子问题是有效的。