SpringMVC开发@Component注解类被两次实例化问题分析与解决

在SpringMVC开发中遇到@Component注解的类被两次实例化的问题。分析发现,由于web.xml中DispatcherServlet与ContextLoaderListener共享ApplicationContext,两者在启动时分别进行实例化。调整为@Service注解后,问题解决,启动日志中start()方法只打印一次。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  需要写一个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.youkuaiyun.com/uyehgdhg/article/details/9463875



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值