自动装配在ContextLoaderListener中不起作用

时间:2017-05-14 13:56:00

标签: java spring

我对Spring很陌生,我不知道为什么Autowired在我的项目中不起作用。

基本上我想使用TimerTask每5秒打印一次内存使用情况,我想在我的自定义监听器中创建TimerTask,扩展ContextLoaderListener。但是,logMemoryTask中的MyContextListener始终为空,有人可以告诉我如何解决此问题吗?提前谢谢!

MyContextListener.java

public class MyContextListener extends ContextLoaderListener {
    @Autowired
    LogMemoryTask logMemoryTask;
    public MyContextListener() {
        super();
        startLogMemory();
    }
    private void startLogMemory() {
        if (logMemoryTask != null) {
            logMemoryTask.run();
        } else {
            System.out.println("LogMemoryTask is null!"); //It always prints null
        }
    }
}

LogMemoryTask.java

public class LogMemoryTask extends TimerTask {
    @Autowired()
    @Qualifier("persistService")
    ILog<MemoryLog> persistService;
    @Override
    public void run() {
        ...
        if (persistService != null) {
            persistService.addLog(
                    new MemoryLog(Long.toString(maxMemory), Long.toString(allocatedMemory), Long.toString(freeMemory)));
        } else {
            // logger.info("persistService is empty!");
            System.out.println("persistService is empty!");
        }
}

我的applicationContext定义

<bean id="persistService" class="com.james.reg.service.PersistService">
    <property name="operationMapper" ref="operationMapper" />
    <property name="memoryLogMapper" ref="memoryLogMapper" />
</bean>
<bean id="logMemoryTask" class="com.james.reg.util.LogMemoryTask"></bean>

1 个答案:

答案 0 :(得分:0)

好的,最后我决定暂时放弃Autowired,并找到另一种方法来实现我的目标。

首先,我覆盖contextInitialized以手动获取我想要的bean,并将实例传递到我想要的位置:

public class MyContextListener extends ContextLoaderListener {
    private LogMemoryTask logMemoryTask;
    ILog<MemoryLog> persistService;
    private Timer t;
    @Override
    public void contextInitialized(javax.servlet.ServletContextEvent event) {
        super.contextInitialized(event);
        WebApplicationContext servletContext = WebApplicationContextUtils
                .getWebApplicationContext(event.getServletContext());
        persistService = (ILog<MemoryLog>) servletContext.getBean("persistService"); // get the bean
        startLogMemory(persistService);
    }
    ...
}

startLogMemory()中,我可以手动创建LogMemoryTask的实例:

public class MyContextListener extends ContextLoaderListener {
    private LogMemoryTask logMemoryTask;
    ILog<MemoryLog> persistService;
    private Timer t;
    private void startLogMemory(ILog<MemoryLog> persistService) {
        t = new Timer();
        logMemoryTask = new LogMemoryTask(persistService);
        t.schedule(logMemoryTask, 0, 5000); // log the memory every 5 seconds
    }
    ...
}

最后完成LogMemoryTask的ctor,并覆盖run方法:

public class LogMemoryTask extends TimerTask {
    private ILog<MemoryLog> persistService;
    public LogMemoryTask(ILog<MemoryLog> persistService) {
        super();
        this.persistService = persistService;
    }
    @Override
    public void run() {
         // do what you want to do periodically here
         ...
    }
    ...
}

现在,当项目开始运行时,监听器将获取bean,并启动计时器以记录内存使用情况。我希望以后可以更优雅的方式......