SpringBoot架构下, 默认开启了自动配置, 在启动后会自动扫描包下的/META-INF/spring.factories文件, 自动加载文件中配置的类.
async-spring-boot-starter
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cloud.async</groupId>
<artifactId>async-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<name>async-spring-boot-starter</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
</project>
通用接口Async
@FunctionalInterface
public interface Async extends Runnable {
void run();
}
默认拒绝策略DefaultRejectHandler
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
public class DefaultRejectHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
throw new RuntimeException("Async thread pool is full");
}
}
配置类AsyncConfiguration
@Configuration
public class AsyncConfiguration {
@Value("${async.coreSize:4}")
private int coreSize;
@Value("${async.blockingSize:10000}")
private int blockingSize;
@Value("${async.rejectHandlerName:}")
private String rejectHandlerName;
@Bean
public AsyncTemplate asyncTemplate() {
return new AsyncTemplate();
}
// 设置线程池
@Bean
public ThreadPoolExecutor asyncExecutor() {
RejectedExecutionHandler handler = new DefaultRejectHandler();
if (rejectHandlerName != null && !rejectHandlerName.equals("")) {
try {
Class handlerClass = Class.forName(rejectHandlerName);
if (handlerClass != null) {
handler = (RejectedExecutionHandler) handlerClass.newInstance();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return new ThreadPoolExecutor(
coreSize,
coreSize,
5,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(blockingSize),
handler);
}
}
AsyncTemplate
public class AsyncTemplate {
@Autowired
private ThreadPoolExecutor executor;
public void run(Async async) {
if (async == null) {
return;
}
Thread thread = new Thread(async);
executor.submit(thread);
}
}
重点 /resources/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.cloud.async.configuration.AsyncConfiguration
使用starter
pom.xml引入
<dependency>
<groupId>com.cloud.async</groupId>
<artifactId>async-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
application.yml
async:
blockingSize: 5 ## 限定个数 测试使用
rejectHandlerName: com.cloud.async.ext.MyRejectHandler
Controller
@RestController
public class IndexController {
@Value("${async.rejectHandlerName}")
private String rejectHandlerName;
@Autowired
private AsyncTemplate asyncTemplate;
@ResponseBody
@GetMapping("/async")
public String async() {
asyncTemplate.run(() -> {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我慢慢执行");
});
System.out.println("我先执行了");
return null;
}
}
运行结果
本文只是简单模拟了一下starter组件的原理, 其功能并没有实际意义, 只做参考…