错误: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配置成功,先记录下来,有好的方法再改进。