2
public class ProcessSchedulerServlet implements javax.servlet.Servlet {
    Timer timer=new Timer();

    @Override
    public void init(ServletConfig arg0) throws ServletException {
        timer.scheduleAtFixedRate(new TimerTask() {
        public void run() {
            LogProcessorService logProcessorService=new LogProcessorServiceImpl();
            logProcessorService.processPageRequestsLogs();
        }
     }, 60*1000, 120*1000);
}

这很丑陋,无论如何也不起作用。LogProcessorServiceImpl 具有带有 @Autowired 注释的属性。当此代码运行时,这些属性不会自动装配。这可能是意料之中的。

真正的问题是:如何使这个 run() 方法起作用。在我看来,Spring 希望 logProcessorService 自动装配,以便在 LogProcessorServiceImpl 中自动装配属性。

=== 场景 1 ============================================== ==================

public void run() {
    final LogProcessorService logProcessorService=null;
    WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext()).getAutowireCapableBeanFactory().autowireBean(logProcessorService);
    logProcessorService.processPageRequestsLogs();
}

结果:编译时错误:无法引用以不同方法定义的内部类中的非最终变量 arg0

=== 场景 2 ============================================== ==================

@Autowired
LogProcessorService logProcessorService;
public void run() {
    logProcessorService.processPageRequestsLogs();
}

结果:运行时错误:logProcessorService 为空;

====解决方案(来自鲍里斯)========================================== ==============

public class ProcessSchedulerServlet implements javax.servlet.Servlet {
    Timer timer=new Timer();

    @Autowired
    LogProcessorService logProcessorService;

    @Override
    public void init(ServletConfig arg0) throws ServletException {
        final AutowireCapableBeanFactory autowireCapableBeanFactory=WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext()).getAutowireCapableBeanFactory();
        autowireCapableBeanFactory.autowireBean(this);

        timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {
                logProcessorService.processPageRequestsLogs();
            }
        }, 60*1000, 120*1000);
}
4

1 回答 1

4

Timer如果 Spring 具有内置的调度支持,为什么还要使用 servlet 和类:

@Service
public class LogProcessorService {

    @Scheduled(fixedRate=120*1000, initialDelay=60*1000)
    public void processPageRequestsLogs() {
        //...
    }

}

而已!没有计时器、runnables 和 servlet。注意:initialDelay在 Spring 3.2 M1 中引入(参见SPR-7022)。

于 2012-11-18T11:56:42.243 回答