1. Principle of SpringBoot automatic configuration

  • from@SpringBootApplicationThe 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@EnableAutoConfigurationBegan 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 inMETA-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
  • inspring.factoriesThere 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
  • RedisPropertiesConfiguration 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 athread-pool-execute-starterThe 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
  • inresourcesIn 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