刷新@ApplicationScoped bean给出nullpointer

时间:2016-09-15 14:16:43

标签: web web-applications cdi servletcontextlistener

首先,我想清楚我知道NullPointerException是什么以及如何处理。我的问题是如何通过我想每天运行一次的调度程序来访问在服务器启动时创建的@ApplicationScoped bean。我现在得到的只是一个新的bean,它在开头是null而不是已经创建的bean。 调度程序执行bean的启动,因此我最终得到两个bean,一个由调度程序(始终)更新,另一个在Web应用程序中导航时使用。

因此...

我有一个带有@ApplicationScoped bean的Web应用程序。这个是从Tomcat启动时的数据库加载的。 这意味着如果在数据库中以某种其他方式更改某些内容,而不是通过Web应用程序,那么在重新启动Tomcat之前,更改将无法查看。 所以我想我可以制定一个计划,在白天的特定时间重新加载这个@ApplicationScoped bean。麻烦的是我得到了一个全新的@ApplicationScoped bean。 那么我该如何更新当前的bean而不是新的呢?

我已经尝试过这个问题的解决方案:Refresh/Reload Application scope managed bean没有任何运气。我的豆仍然是null

我还在没有真正解决问题的情况下查看了以下主题:

application scoped bean's view is not updated

Access ApplicationScoped bean through ServletContext

我的ApplicationBean.java

import javax.enterprise.context.ApplicationScoped;

@Named(value = "applicationBean")
@ApplicationScoped
public class ApplicationBean {
    @PostConstruct
    public void init() {
        //load variables from db
    }
}

我的ScheduleTaskConfig.java

@WebListener
public class ScheduleTaskConfig implements ServletContextListener {

    private ScheduledExecutorService scheduler;

    @Override
    public void contextInitialized(ServletContextEvent event) {
        Reloader reloader = new Reloader(event.getServletContext());
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(reloader, 2, 3, TimeUnit.MINUTES);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        scheduler.shutdownNow();
    }
}

My Reloader.java

public class Reloader implements Runnable {

    private ServletContext context;

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

    @Override
    public void run() {
        ApplicationBean applicationBean = (ApplicationBean) context.getAttribute("applicationBean");
        if (applicationBean != null) {
            applicationBean.init();
        }
    }
}

我只是不知道出了什么问题。我不明白如何解决这个问题。

我知道我已经写过时间表应该每隔3分钟运行一次但是当我开始工作时,时间表应该每天运行一次。

有更好的方法可以做到这一点还是我忘记了什么?我一整天都用Google搜索,没有前进,所以我真的需要帮助。 谢谢。

编辑: 所以我的servlet上下文已经启动,我的应用程序上下文启动之前会通知我的监听器? 如果我使用网页然后我的应用程序上下文(?)但我的调度程序仍然无法工作,那么调度程序中的bean仍然是一个新的,而不是我在导航时使用的那个网络应用程序。或者我只是对此感到困惑? :) 谢谢你的帮助。

编辑: 我使用的是Primefaces 6.0,我想这个bean是一个JSF bean。使用的其他bean是从模型类导入的Spring bean。很抱歉我已经删除了Spring表示法,并添加了Primefaces。 我希望这能解决问题。谢谢

0 个答案:

没有答案