我创建了一个类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);
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 ...");
...
ModuleBean.java
package de.whatever;
@ManagedBean (name="modOverview")
@ApplicationScoped
public class ModuleOverviewBean {
private String randomData;
我的问题是如何在我的应用程序bean中将数据设置为 randomData 字段。
我读到我可以从ServletContext加载属性“modOverview”,但返回null。
加载和设置值的正确方法是什么?
我正在使用JBoss(没有spring)。
由于 Hauke
答案 0 :(得分:4)
如果它返回null
,那么它只是意味着JSF还没有创建它。只需自己创建一个。当应用程序范围内已存在时,JSF不会覆盖它。您只需要知道,不会自动设置此类的任何托管属性。
ModuleOverviewBean bean = (ModuleOverviewBean) servletContext.getAttribute("modOverview");
if (bean == null) {
bean = new ModuleOverviewBean();
servletContext.setAttribute("modOverview", bean);
}
// ...
无关问题,java.util.Timer
是在Java EE应用程序中执行后台作业的一种非常糟糕的方式。至少在ScheduledExecutorService
,或者因为你已经在使用JBoss,@Singleton
带有@Schedule
方法的EJB。
更新:如果您还关注托管属性的设置,您还可以尝试使用eager=true
注释托管bean,如下所示,以便JSF在webapp的启动时自动创建它: / p>
@ManagedBean(name="modOverview", eager=true)
我只是不确定这是否会在ServletContextListener
运行之前运行。我想会的。但是,如果您使用@Singleton
EJB @Schedule
,它肯定会有效。