1 设置properties 文件
@Component
@Data
@ConfigurationProperties("thread-pool")
public class ThreadPoolProperties {
private int corePoolSize;
private int maxPoolSize;
private int queueCapacity;
private int keepAliveSeconds;
private String threadPrefix;
private String name;
}
2 解析properties 文件
@Slf4j
@Configuration
@ConditionalOnClass(ThreadPoolProperties.class)
public class ThreadPoolAutoConfiguration {
@Bean
public static ThreadPoolBeanDefinitionRegistryPostProcessor threadPoolBeanDefinitionRegistryPostProcessor() {
return new ThreadPoolBeanDefinitionRegistryPostProcessor();
}
static class ThreadPoolBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware {
//
private static final String POOL_PREFIX = "thread-pool";
private Environment environment;
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
List<ThreadPoolProperties> poolProperties = new ArrayList<>();
ThreadPoolProperties p = Binder.get(environment).bind(POOL_PREFIX, Bindable.of(ThreadPoolProperties.class)).orElse(null);
if (p != null) {
poolProperties.add(p);
} else {
// 多消费者配置
List<ThreadPoolProperties> propertiesList = Binder.get(environment).bind(POOL_PREFIX, Bindable.listOf(ThreadPoolProperties.class)).orElse(Collections.emptyList());
if (CollectionUtils.isNotEmpty(propertiesList)) {
poolProperties.addAll(propertiesList);
}
}
if (CollectionUtils.isEmpty(poolProperties)) {
return;
}
poolProperties.stream().forEach(properties->{
log.info("start " + properties.getThreadPrefix());
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//配置核心线程数
executor.setCorePoolSize(properties.getCorePoolSize());
//配置最大线程数
executor.setMaxPoolSize(properties.getMaxPoolSize());
//配置队列大小
executor.setQueueCapacity(properties.getQueueCapacity());
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix(properties.getName()+"_");
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
BeanFactory.addPool(properties.getName(), executor);
});
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
}
}
为了可以通过名称获取,我放了一个map
public class BeanFactory {
public static final ConcurrentHashMap<String, Executor> threadPoolMap = new ConcurrentHashMap<>();
public static void addPool(String name,Executor executor){
threadPoolMap.put(name,executor);
}
public static Executor getPool(String name){
return threadPoolMap.get(name);
}
}
3 application.yml 配置
thread-pool:
- corePoolSize: 9
maxPoolSize: 9
queueCapacity: 100
keepAliveSeconds: 120
name: testPool
- corePoolSize: 10
maxPoolSize: 10
queueCapacity: 100
keepAliveSeconds: 120
name: testPool1
关联知识点
BeanDefinitionRegistryPostProcessor,Bean 生命周期的后置处理器
beanDefinitionRegistry.registerBeanDefinition(properties.getName(), BeanDefinitionBuilder.
genericBeanDefinition(ThreadPoolTaskExecutor.class, () -> executor).getBeanDefinition());
这种写法也可以用InitializingBean
todo
拒绝策略可以通过配置雷鸣解析完成