More than one TaskScheduler and/or ScheduledExecutorService exist within the context

2 篇文章 0 订阅
1 篇文章 0 订阅

错误:spring netty 注解多个NioEventLoopGroup ScheduledExecutorServicebean时,报以下错误:

java.lang.IllegalStateException: More than one TaskScheduler and/or ScheduledExecutorService  exist within the context. Remove all but one of the beans; or implement the SchedulingConfigurer interface and call ScheduledTaskRegistrar#setScheduler explicitly within the configureTasks() callback. Found the following beans: [bossGroup, workerGroup]

注解多个NioEventLoopGroup bean时:

	@Bean(name = "bossGroup", destroyMethod = "shutdownGracefully")
	public NioEventLoopGroup bossGroup() {
		return new NioEventLoopGroup(bossCount); //NioEventLoopGroup 继承与 ScheduledExecutorService
	}

	@Bean(name = "workerGroup", destroyMethod = "shutdownGracefully")
	public NioEventLoopGroup workerGroup() {
		return new NioEventLoopGroup(workerCount); //NioEventLoopGroup 继承与 ScheduledExecutorService
	}

原因:    默认的是单线程,设置多个的时候报错

 参考 http://www.icoder.name/post/gong-zuo-ri-zhi/2015-09-10-spring_schedul

public class ScheduledAnnotationBeanPostProcessor
		implements BeanPostProcessor, Ordered, EmbeddedValueResolverAware, ApplicationContextAware,
		ApplicationListener<ContextRefreshedEvent>, DisposableBean {
public void onApplicationEvent(ContextRefreshedEvent event) {
		if (event.getApplicationContext() != this.applicationContext) {
			return;
		}
		Map<String, SchedulingConfigurer> configurers =
				this.applicationContext.getBeansOfType(SchedulingConfigurer.class);
		if (this.scheduler != null) {
			this.registrar.setScheduler(this.scheduler);
		}
		for (SchedulingConfigurer configurer : configurers.values()) {
			configurer.configureTasks(this.registrar);
		}
		if (this.registrar.hasTasks() && this.registrar.getScheduler() == null) {
			Map<String, ? super Object> schedulers = new HashMap<String, Object>();
			schedulers.putAll(applicationContext.getBeansOfType(TaskScheduler.class));
			schedulers.putAll(applicationContext.getBeansOfType(ScheduledExecutorService.class));
			if (schedulers.size() == 0) {
				// do nothing -> fall back to default scheduler
			}
			else if (schedulers.size() == 1) {
				this.registrar.setScheduler(schedulers.values().iterator().next());
			}
			else if (schedulers.size() >= 2){
				throw new IllegalStateException(
						"More than one TaskScheduler and/or ScheduledExecutorService  " +
						"exist within the context. Remove all but one of the beans; or " +
						"implement the SchedulingConfigurer interface and call " +
						"ScheduledTaskRegistrar#setScheduler explicitly within the " +
						"configureTasks() callback. Found the following beans: " + schedulers.keySet());
			}
		}
		this.registrar.afterPropertiesSet();
	}
 

	/**
	 * Schedule all registered tasks against the underlying {@linkplain
	 * #setTaskScheduler(TaskScheduler) task scheduler}.
	 */
	protected void scheduleTasks() {
		long now = System.currentTimeMillis();

		if (this.taskScheduler == null) {//默认的是单线程,设置多个的时候报错
			this.localExecutor = Executors.newSingleThreadScheduledExecutor();
			this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
		}
		if (this.triggerTasks != null) {
			for (TriggerTask task : triggerTasks) {
				this.scheduledFutures.add(this.taskScheduler.schedule(
						task.getRunnable(), task.getTrigger()));
			}
		}
		if (this.cronTasks != null) {
			for (CronTask task : cronTasks) {
				this.scheduledFutures.add(this.taskScheduler.schedule(
						task.getRunnable(), task.getTrigger()));
			}
		}
		if (this.fixedRateTasks != null) {
			for (IntervalTask task : fixedRateTasks) {
				if (task.getInitialDelay() > 0) {
					Date startTime = new Date(now + task.getInitialDelay());
					this.scheduledFutures.add(this.taskScheduler.scheduleAtFixedRate(
							task.getRunnable(), startTime, task.getInterval()));
				}
				else {
					this.scheduledFutures.add(this.taskScheduler.scheduleAtFixedRate(
							task.getRunnable(), task.getInterval()));
				}
			}
		}
		if (this.fixedDelayTasks != null) {
			for (IntervalTask task : fixedDelayTasks) {
				if (task.getInitialDelay() > 0) {
					Date startTime = new Date(now + task.getInitialDelay());
					this.scheduledFutures.add(this.taskScheduler.scheduleWithFixedDelay(
							task.getRunnable(), startTime, task.getInterval()));
				}
				else {
					this.scheduledFutures.add(this.taskScheduler.scheduleWithFixedDelay(
							task.getRunnable(), task.getInterval()));
				}
			}
		}
	}


解决办法:    添加额外的实现来隔离它们

             参考:http://stackoverflow.com/questions/21758116/why-does-spring-4-only-allow-one-taskscheduler-in-a-context

方法1:

    @Bean(name = "bossGroup", destroyMethod = "shutdownGracefully")
    public NioEventLoopGroup bossGroup() {
        return new NioEventLoopGroup(bossCount); //NioEventLoopGroup 继承与 ScheduledExecutorService
    }

    @Bean(name = "workerGroup", destroyMethod = "shutdownGracefully")
    public NioEventLoopGroup workerGroup() {
        return new NioEventLoopGroup(workerCount); //NioEventLoopGroup 继承与 ScheduledExecutorService
    }
	    
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        
        // TODO Auto-generated method stub
        taskRegistrar.setTaskScheduler(taskScheduler());
        //taskRegistrar.setScheduler(scheduler)
        /*taskRegistrar.addFixedRateTask(new Runnable()
        {
           public void run()
           {
              timedThingy().sendIt();
           }
        }, 1000);*/

    }
	
    @Bean(destroyMethod="shutdown")
    public ThreadPoolTaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler ts =  new ThreadPoolTaskScheduler();
        ts.setPoolSize(1);
        return ts;
    }
   

方法2:   

<beans>
    <task:annotation-driven scheduler="taskScheduler"/>
    <task:scheduler id="taskScheduler" pool-size="1"/>
    <task:scheduled ref="myTask" method="work" fixed-rate="1000"/>
    <bean id="myTask" class="com.foo.MyTask"/>
</beans>

后记:错误已经解决,感觉不是很优雅,netty与spring配置成功,先记录下来,有好的方法再改进。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值