我需要每天运行一个进程,以便在服务器上进行维护工作(更新记录)。
我有一个单例范围类,它运行一个计时器和一个内部类,注入我需要的服务。当我运行该程序时,计时器抛出NullPointerException,因为该服务尚未注入。
@Named("demonService")
@Singleton
public class DemonImpl implements IDemonService
{
private static Logger log = Logger.getLogger(DemonioImpl.class);
@PostConstruct
public void init()
{
log.info("-->Demon");
Calendar today = new GregorianCalendar();//Every day at 2:00am (from now)
today.set(Calendar.HOUR_OF_DAY, 2);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.SECOND, 0);
try
{
Timer timer = new Timer(true);
timer.schedule(new Updater(), today.getTime(), 24*60*60*1000);
}
catch(Exception e)
{
log.fatal(e.getLocalizedMessage());
e.printStackTrace();
}
log.info("--> Demon: exit");
}
private class Updater extends TimerTask
{
private Logger log = Logger.getLogger(Updater.class);
@Inject
@Named("updaterService")
private IUpdaterService updaterService;
@Override
public void run()
{
log.info("Task: update records (start)");
List<Record> list = updaterService.getAll();//<-- This throws the exception
for(Record item : list)
{
updaterService.update(item);
}
log.info("Task: update records (exit)");
}
}
错误是
Exception in thread "Timer-3" java.lang.NullPointerException
at test.service.impl.DemonImpl$Updater.run(DemonImpl.java:66)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
除了这个类,应用程序工作正常。如何在应用程序完全正常工作时注入服务?
答案 0 :(得分:0)
CDI将不会管理实例,因为您通过自己调用构造函数来实例化Updater
。
现在有两种方法可以解决这个问题:
Updater
中注入DemonImpl
类的实例并使用该实例。Provider<Updater>
中注入DemonImpl
实例并从中获取Updater
类的新实例,在运行时创建新的CDI托管实例。答案 1 :(得分:0)
当Class不是CDI Bean时,通常你有一个NPE。如果您创建新的Updater(),则CDI不会考虑这一点。你必须在Singleton中@Inject the Updater。