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

来源:互联网 发布:mac不能拷贝到移动硬盘 编辑:程序博客网 时间:2024/05/22 05:06

错误: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 ScheduledAnnotationBeanPostProcessorimplements 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 0
原创粉丝点击