天天看點

SpringMVC開發@Component注解類被兩次執行個體化問題分析與解決

  需要寫一個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類。

SpringMVC開發@Component注解類被兩次執行個體化問題分析與解決

但是不知為何@Component注解的類這兩次都不放過。

于是将@Component注解修改為@Service,日志中start()隻列印一次了,解決之。

參考文章:

http://www.cnblogs.com/mypm/p/3164737.html

http://blog.csdn.net/uyehgdhg/article/details/9463875