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