1. Principle of SpringBoot automatic configuration
- from
@SpringBootApplication
The annotation begins by saying that the annotation is a compound annotation made up of the following annotations.
// For other configuration classes, @springBootConfiguration // Automatically configures the most important annotation @enableAutoConfiguration // for scanning other annotations (@service, @Controller), etc @ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} )Copy the code
- The following from
@EnableAutoConfiguration
Began to speak
It was one of the key this AutoConfigurationImportSelector class @ Import ({AutoConfigurationImportSelector. Class})Copy the code
GetAutoConfigurationEntry in him selectImports method is to get an important automatic configuration
public String[] selectImports(AnnotationMetadata annotationMetadata) { if (! this.isEnabled(annotationMetadata)) { return NO_IMPORTS; } else { AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata); return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); } } protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { if (! this.isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } else { AnnotationAttributes attributes = this.getAttributes(annotationMetadata); List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes); configurations = this.removeDuplicates(configurations); Set<String> exclusions = this.getExclusions(annotationMetadata, attributes); this.checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = this.getConfigurationClassFilter().filter(configurations); this.fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions); }}Copy the code
- Through the above acquisition in
META-INF/spring.factories
.
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
Copy the code
- in
spring.factories
There will be many such key-value pairs in
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
Copy the code
When SpringBoot starts, xxxAutoConfigureation is loaded. This section uses RedisAutoConfiguration as an example to describe how to configure xxxAutoConfigureation.
// Only those who meet this requirement, @conditionalonClass ({redisoperations.class}) // open the config class @EnableConfigurationProperties({RedisProperties.class}) @Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class}) public class RedisAutoConfiguration {Copy the code
RedisProperties
Configuration class, if you look at this class, if you’re familiar with it, it’s what we configure in YML
@ConfigurationProperties(
prefix = "spring.redis"
)
public class RedisProperties {
private int database = 0;
private String url;
private String host = "localhost";
private String username;
private String password;
private int port = 6379;
private boolean ssl;
private Duration timeout;
private Duration connectTimeout;
private String clientName;
}
Copy the code
Summary: The implementation of the above process will quickly configure, reduce the tedious XML configuration, if you want to configure, simply configure in YML.
2. Customize the starter to create a thread pool
- To create a
thread-pool-execute-starter
The engineering of
</groupId> <artifactId> thread-pool-execut-starter </artifactId> <version>1.0</version> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> </dependencies>Copy the code
- Auto-configuration class
@ Configuration / / Configuration Configuration properties @ EnableConfigurationProperties (ThreadPoolExecutorProperties. Class) / / only the class of the school @ ConditionalOnClass (ThreadPoolExecutor. Class) public class ThreadPoolAutoConfiguration {/ * * * * / private final blocking queue BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(4); / rejection policies * * * * / private final RejectedExecutionHandler reject = new ThreadPoolExecutor. AbortPolicy (); /** * Thread pool type: CPU intensive: 1; @value ("${thread.pool.scenes}") private Integer scenes; /** * corePoolSize; private Integer corePoolSize; /** * Maximum number of threads */ private Integer maximumPoolSize; /** * Private Long keepAliveTime; /** * private TimeUnit unit; @construct public void init() {cpuCoreNumber = Runtime.getruntime ().availableprocessors (); this.corePoolSize = cpuCoreNumber; this.maximumPoolSize = 25 * cpuCoreNumber; this.keepAliveTime = 60 * 3L; this.unit = TimeUnit.SECONDS; } /** * N: Number of CPU cores x CPU intensity: corePoolSize = N + 1 X IO intensity: CorePoolSize = 2 * N */ @bean public ThreadPoolExecutor ThreadPoolExecutor () {if (scenes == 1) {corePoolSize = corePoolSize + 1; } else {// corePoolSize = 2; } return new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, reject); }}Copy the code
- Configuring class Properties
@ConfigurationProperties( prefix = "thread.pool" ) public class ThreadPoolExecutorProperties { private Integer scenes = 1; public Integer getScenes() { return scenes; } public void setScenes(Integer scenes) { this.scenes = scenes; }}Copy the code
- in
resources
In the newMETA-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.angel.item.ThreadPoolAutoConfiguration
Copy the code
Repackage the project, MVN Clean install -u
- Introduce the above coordinates in another project
<dependency> <groupId>com.angel.item</groupId> <artifactId>thread-pool-execute-starter</artifactId> The < version > 1.0 < / version > < / dependency >Copy the code
- Configure it in YML
thread:
pool:
scenes: 1
Copy the code
MVN Package is repackaged
Summary: With the above configuration, a custom starter can be implemented