Springboot学习笔记(六)-配置化注入
前言
前面写过一个Springboot学习笔记(一)-线程池的简化及使用,发现有个缺陷,打个比方,我这个线程池写在一个公用服务中,各项参数都定死了,现在有两个服务要调用它,一个服务的线程数通常很多,而另一个则很少,那么线程多的服务会感觉这个线程池小,另一个又觉得浪费资源,这样很不灵活,所以希望将这个线程池被引用的时候可以自定义配置。比如在配置文件中写下线程池的核心线程数,最大线程数等等,根据不同的需要配置不同的参数。
实现
思路
前面学过【转】Spring Boot干货系列:(二)配置文件解析和条件化注入Springboot学习笔记(五)-条件化注入,有了这个基础,就可以写一个配置映射类,同时定义一个自动配置类,将配置映射类中的属性拷贝过来。
实现
配置映射类
ThreadPoolProperties:
@ConfigurationProperties(prefix = "thread", ignoreUnknownFields = false)
public class ThreadPoolProperties {
private int corePoolSize;
private int maxPoolSize;
private int queueCapacity;
private String threadNamePrefix;
private RejectedExecutionHandler rejectedExecutionHandler;
private boolean waitForTasksToCompleteOnShutdown;
public int getCorePoolSize() {
return corePoolSize;
}
public void setCorePoolSize(int corePoolSize) {
this.corePoolSize = corePoolSize;
}
public int getMaxPoolSize() {
return maxPoolSize;
}
public void setMaxPoolSize(int maxPoolSize) {
this.maxPoolSize = maxPoolSize;
}
public int getQueueCapacity() {
return queueCapacity;
}
public void setQueueCapacity(int queueCapacity) {
this.queueCapacity = queueCapacity;
}
public String getThreadNamePrefix() {
return threadNamePrefix = Optional.ofNullable(threadNamePrefix).orElse("");
}
public void setThreadNamePrefix(String threadNamePrefix) {
if (threadNamePrefix == null || "".equals(threadNamePrefix)) {
this.threadNamePrefix = "default-thread-pool";
return;
}
if (!threadNamePrefix.endsWith("-")) {
this.threadNamePrefix = threadNamePrefix + "-";
return;
}
this.threadNamePrefix = threadNamePrefix;
}
public RejectedExecutionHandler getRejectedExecutionHandler() {
return rejectedExecutionHandler;
}
public void setRejectedExecutionHandler(int rejectedExecutionHandler) {
switch (rejectedExecutionHandler) {
case 1:
this.rejectedExecutionHandler = new ThreadPoolExecutor.CallerRunsPolicy();
break;
case 2:
this.rejectedExecutionHandler = new ThreadPoolExecutor.DiscardOldestPolicy();
break;
case 3:
this.rejectedExecutionHandler = new ThreadPoolExecutor.DiscardPolicy();
break;
default:
this.rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();
break;
}
}
public boolean isWaitForTasksToCompleteOnShutdown() {
return waitForTasksToCompleteOnShutdown;
}
public void setWaitForTasksToCompleteOnShutdown(boolean waitForTasksToCompleteOnShutdown) {
this.waitForTasksToCompleteOnShutdown = waitForTasksToCompleteOnShutdown;
}
}
自动配置类
ThreadPoolAutoConfiguration:
@Configuration
@EnableConfigurationProperties(ThreadPoolProperties.class)
@ConditionalOnProperty(name = "thread.corePoolSize")
public class ThreadPoolAutoConfiguration {
private final ThreadPoolProperties threadPoolProperties;
@Autowired
public ThreadPoolAutoConfiguration(ThreadPoolProperties threadPoolProperties) {
this.threadPoolProperties = threadPoolProperties;
}
@Bean
@ConditionalOnMissingBean(ThreadPoolTaskExecutor.class)
public ThreadPoolTaskExecutor taskService() {
ThreadPoolTaskExecutor service = new ThreadPoolTaskExecutor();
BeanUtils.copyProperties(threadPoolProperties, service);
return service;
}
}
配置文件
thread.corePoolSize=4
thread.maxPoolSize=5
thread.queueCapacity=20
thread.threadNamePrefix=hello
thread.rejectedExecutionHandler=1
thread.waitForTasksToCompleteOnShutdown=true
这时有个问题,自动配置有两种方式,一种是在启动时直接加载,另外一种是定义一个开关,一般是定义一个名字有意义的注解,当有这个注解的时候再加载和注入自动配置。
启动直接加载
启动加载比较简单,仿照官方做,就是在配置根目录下定义一个spring.factories
文件,它是用来在启动时读取的,找到对应的配置类则直接加载注入,格式如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.yan.thread.pool.starter.config.ThreadPoolAutoConfiguration
使用开关加载
定义一个开关注解,就叫EnableThreadPool
,通过在其上标注@Import(ThreadPoolImportSelector.class)
来注入自动配置类ThreadPoolAutoConfiguration
。
ThreadPoolImportSelector:
public class ThreadPoolImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{ThreadPoolAutoConfiguration.class.getName()};
}
}
EnableThreadPool:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ThreadPoolImportSelector.class)
public @interface EnableThreadPool {
}
属性文件自动提示
一般在我们开发中,属性文件会产生一个自动提示,这个自定义提示也可以把我们的配置类添加到提示中。
真正起作用的是META-INF/spring-configuration-metadata.json文件,springboot为我们提供了便捷方式,可以自动生成此文件,步骤如下:
引入jar包
dependencies {
compile "org.springframework.boot:spring-boot-configuration-processor"
}
在idea设置中搜索Annotation Processors,接下来勾住Enable annonation processing就完成了。
编译后即可看到自动生成的spring-configuration-metadata.json。
注
有些人习惯叫***-starter,并把它单独抽成一个服务,打成jar包供外部工程使用,我还是习惯叫配置化注入。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix