需要写一个Job类,思路是利用Job实例初始化的时候启动一个ScheduleExecutorTask,定时update一些东西。
@Component("RefreshJob")
public class RefreshJob{
@PostConstruct
public void start(){
logger.info("start()". + this);
ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1);
executor.scheduleAtFixedRate(new Runnable(){
public void run(){
try{
update();
}
catch(Exception exp){
}
}
}, 0, 1, TimeUnit.MINUTES);
}
Component本来是单例的,@PostConstruct是在实例化完成后调用的方法。但是日志中start()出现了两次,并且this的地址不同,很明显,RefreshJob实例化了两次,造成两个Job实例在同时运行。
求Google,结合两篇文章的答案,分析得出:
web.xml中的DispatcherServlet继承自ContextLoaderListener,两者共用ApplicationContext,但是在启动的时候,会分别调用initWebApplicationContext()方法,各自对@Component注解对象实例化一次,DispatcherServlet调用在后,在Controller中使用的是后面实例化的对象。
牛人A修改了Spring的源代码解决之,但是后续影响未见其返回。
文章中进一步解释其实例化类的范围不同,ContextLoaderListerner实例化DataSource/Dao/Service等其他Bean,DispatcherServlet初始化Controller/ViewResolver/HandlerMapping/HandlerAdapter相关web类。
但是不知为何@Component注解的类这两次都不放过。
于是将@Component注解修改为@Service,日志中start()只打印一次了,解决之。
参考文章:
http://www.cnblogs.com/mypm/p/3164737.html
http://blog.csdn.net/uyehgdhg/article/details/9463875