Be serious about writing, not clickbait.

The article is available at Github.com/niumoo/Java… And program ape Alang’s blog, point attention, don’t get lost.

1. Introduction

Automatic configuration in Springboot is really convenient, reducing the complexity of our development, so what is the principle of automatic configuration? I wrote an article about it earlier. Spring Boot (3) Automatic configuration of Spring Boot.

Since autoconfiguration uses configuration file bindings, you can refer to this article if you don’t already know how to use common configuration files. Spring Boot configuration file.

This time, you’ll learn more about automatic configuration by learning the Springboot automatic configuration mode and writing your own starter.

Familiar with the mode, help to improve the standardization of written starter, before writing their own starter to learn the official Springboot starter and common framework integration starter writing way, you can appreciate the mystery.

2. Springboot official mode

Select an official automatic configuration for analysis, here select the common configuration port number configuration.

2.1. Introduce dependencies

We need to introduce Web dependencies before using port numbers.

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Copy the code

If you watch a lot of Springboot starters, you may have noticed a pattern. The official Springboot starter name is spring-boot-starter-xxxx.

Looking at the Spring-boot-starter-web, you can see that this dependency is an empty box with no line of code other than relying on other POMs.

At this point, another pattern is found: starter only relies on other POMs and does no code to implement them.

So what does spring-boot-starter-Web depend on?

By looking at this dependency information and then referring to other official starters, you can find several fixed imports, which can be called schema dependency imports.

  1. Rely onspring-boot-starter.
  2. Rely onspring-boot-autoconfigure.

2.2. Automatic configuration

Importing dependencies only configures port numbers, like this.

server.port=8090
Copy the code

The configuration binding class file can be found in IDEA by clicking server.port. You can see that the configuration is eventually injected into the Port property of the ServerProperties class.

So where exactly is ServerProperties used? Keep looking and find a call related to the Servlet.

Calls were found ServletWebServerFactoryCustomizer class, the class definition

private final ServerProperties serverProperties;
Copy the code

Properties used to use the configuration. Continue to see this kind of call, found that only one classes use this class, this class is ServletWebServerFactoryAutoConfiguration.

According to our understanding of annotations, this class is the auto-configure main class. Also, auto-configuration classes end in AutoConfiguration.

Look at the meaning of several comments on this class.

  1. The priority is high.
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
Copy the code
  1. Only in theServletRequestClass exists and is a Web application.
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
Copy the code
  1. Open theServerPropertiesConfiguration binding.
@EnableConfigurationProperties(ServerProperties.class)
Copy the code
  1. Several classes are imported.
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, ServletWebServerFactoryConfiguration.EmbeddedTomcat.class, ServletWebServerFactoryConfiguration.EmbeddedJetty.class, ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
Copy the code

The configuration is also injected into the Bean factory for invocation elsewhere.

@Bean
public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties) {
	return new ServletWebServerFactoryCustomizer(serverProperties);
}
Copy the code

Is auto-configuration all that? From the analysis in the previous article, we know that not only the code, but at least one configuration file that specifies the auto-configuration class needs to be read. The spring.factories file.

If you don’t know, read this article first. Spring Boot (3) Automatic configuration of Spring Boot. Indeed, you can find the class traced above in spring.Factories. Namely ServletWebServerFactoryAutoConfiguration.

Based on the above analysis, several modes of Springboot’s official starter can be found.

  1. useXXXPropertiesAutomatic bindingXXXInitial configuration information, such as:ServerProperties.
  2. theXXXPropertiesDefine the class to use, as in:ServletWebServerFactoryCustomizer.
  3. Write aXXXAutoConfigurationOpen,XXXPropertiesTo automatically configure, limit the scenarios, create the required classes toBeanThe factory. Such as:ServletWebServerFactoryAutoConfiguration.

3. Third-party integration mode

It is unrealistic for Springboot officials to write all frameworks as starter. Therefore, many third-party frameworks need to be actively integrated into SpringBoot, so we chose a common framework to analyze its starter implementation. Since we have seen how the official Springboot starter is configured, and third-party frameworks are similar, we will point out the similarities in the following observations rather than comparing them in detail.

Here, mybatis-spring-boot-starter is selected for learning analysis.

3.1 Importing Dependencies

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.2</version>
</dependency>
Copy the code

Here, the starter dependency of mybatis framework conforms to certain rules, namely xxX-spring-boot-starter.

Looking at the starter, it also doesn’t do any code implementation, which is consistent with the SpringBoot official.

Check out mybatis-spring-boot-starter dependencies, there are many, the main ones related to automatic configuration are.

<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-autoconfigure</artifactId>
</dependency>
Copy the code

3.2 Automatic Configuration

Mybatis -spring-boot-autoconfigure = mybatis-spring-boot-autoconfigure = mybatis- Spring-boot-autoconfigure = mybatis

Autoconfiguration of mybatis is also indicated with spring.factories and then with XxxAutoConfiguration binding to XxxProperties.

In principle, and the above springboot official starter is the same, so not too much introduction.

Write your own starter

Having said that, it’s finally time for the hands-on part. From the above introduction, we can roughly figure out the starter step for writing our own.

  1. Create a name likexxx-spring-boot-starterThe initiator project.
  2. Create a name likexxx-spring-boot-autoconfigureThe project.
    • Write property binding classesxxxProperties.
    • Write the service class, introducedxxxProperties.
    • Write automatic configuration classesXXXAutoConfigurationInject configuration.
    • createspring.factoriesFile that specifies the classes to be automatically configured.
  3. The initiator project is an empty project used to importxxx-spring-boot-autoconfigureAnd other dependencies.
  4. Project introductionstarterTo configure the information to be configured.

4.1 Creating an Initiator Project

Since the launcher requires no code implementation and only relies on other projects, create an empty Maven project. But the name should be formal. The starter created here is myapp-spring-boot-starter.

The POM file is as simple as importing myapp-spring-boot-Autoconfigure, which you will create next.


      
<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>net.codingme.starter</groupId>
    <artifactId>myapp-spring-boot-starter</artifactId>
    <version>1.0 the SNAPSHOT</version>
    <! -- Initiator -->
    <dependencies>
        <! -- Introduce automatic configuration project -->
        <dependency>
            <groupId>net.codingme.starter</groupId>
            <artifactId>myapp-spring-boot-autoconfigure</artifactId>
            <version>0.0.1 - the SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>
Copy the code

4.2 Creating an Automatic Configuration Project

With the starter analysis above, create a project named myapp-spring-boot-Autoconfigure. Only the Springboot parent project and spring-boot-starter are introduced in the project.


      
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.0. RELEASE</version>
        <relativePath/> <! -- lookup parent from repository -->
    </parent>
    <groupId>net.codingme.starter</groupId>
    <artifactId>myapp-spring-boot-autoconfigure</artifactId>
    <version>0.0.1 - the SNAPSHOT</version>
    <name>myapp-spring-boot-autoconfigure</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    </dependencies>
</project>

Copy the code

Look at the overall structure of the project.

Use the @configurationProperties (prefix = “myapp.hello”) annotation in HelloProperties to bind the properties in the class to the configuration starting with myApp.hello.

/**
 * <p>
 *
 * @Author niujinpeng
 * @Date2019/10/29 struck * /
@ConfigurationProperties(prefix = "myapp.hello")
public class HelloProperties {

    private String suffix;

    public String getSuffix(a) {
        return suffix;
    }

    public void setSuffix(String suffix) {
        this.suffix = suffix; }}Copy the code

The sayHello method in HelloService then uses the automatically bound value in HelloProperties.

public class HelloService {
    HelloProperties helloProperties;
    
    public String sayHello(String name) {
        return "Hello " + name + "," + helloProperties.getSuffix();
    }
    
    public HelloProperties getHelloProperties(a) {
        return helloProperties;
    }

    public void setHelloProperties(HelloProperties helloProperties) {
        this.helloProperties = helloProperties; }}Copy the code

For HelloService can be injection and can normal use HelloProperties automatically, so we in the HelloProperties HelloServiceAutoConfiguration class. The class introduction, Then inject HelloService into the Bean.

/** * Only web applications take effect */
@ConditionalOnWebApplication
/** * put the properties file into effect */
@EnableConfigurationProperties(HelloProperties.class)
The /*** * declaration is a configuration class */
@Configuration
public class HelloServiceAutoConfiguration {

    @Autowired
    private HelloProperties helloProperties;

    @Bean
    public HelloService helloService(a) {
        HelloService helloService = new HelloService();
        helloService.setHelloProperties(helloProperties);
        returnhelloService; }}Copy the code

Finally, in spring.Factories, you only need to specify which classes you want to configure automatically.

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
net.codingme.starter.HelloServiceAutoConfiguration
Copy the code

At this point, the auto-configuration project is complete. You can run MVN install in the myapp-spring-boot-Autoconfigure project to package the automatic configuration project into the local repository, and then use the same command to install myapp-spring-boot-starter into the repository. Since the latter relies on the former project, the former requires advanced MVN install here.

4.3 Using a Customized Initiator

Create a springboot project myapp-spring-boot-starter-test.

Introduce web dependency, introduce myapp-spring-boot-starter written by myself.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<! -- Introduce your starter -->
<dependency>
    <groupId>net.codingme.starter</groupId>
    <artifactId>myapp-spring-boot-starter</artifactId>
    <version>1.0 the SNAPSHOT</version>
</dependency>
Copy the code

Write a HelloController to inject the HelloService in automatic configuration for testing.

@RestController
public class HelloController {

    @Autowired
    HelloService helloService;

    @GetMapping("/hello")
    public String sayHello(String name) {
        returnhelloService.sayHello(name); }}Copy the code

Since the autoConfigure project defines the sayHello method to output “Hello” + the passed name + the configured hello.suffix, we configure this property in the SpringBoot configuration file.

myapp.hello.suffix=Good morning
Copy the code

Run the test project and pass a name to the /hello path to see if the automatic configuration takes effect.

From the test results, you can see that the automatic configuration of good morning has taken effect. The starter I wrote here is finished.

The project has been uploaded to Github. github.com/niumoo/spri…

Directory of articles in the Springboot series

Springboot Series (1) Spring Boot Starting Springboot series (2) Spring Boot configuration file Springboot series (3) Spring Boot Automatic configuration Springboot series (4) Spring Springboot series (5) Static resources and template engine for Spring Boot Web development Springboot series (6) Interceptors and three components for Spring Boot Web development Springboot series (7) Web Analysis of Springboot series (eight) dynamic Banner and picture to character pattern manual implementation Springboot series (nine) using Spring JDBC and Druid data source monitoring Springboot series (ten) use Mybatis = Mybatis = Mybatis = Mybatis = Mybatis Springboot series (13) Use email service Springboot series (14) quickly enable HTTPS encryption of your website Springboot series (15) how to write your own Springboot starter

After < >

Hello world 🙂

I am a lang, lang of the moon, a technical tool person who moves bricks every day. Personal website: www.wdbyte.com If you want to subscribe, you can follow the public account of “Procedural Ape Alang”, or the blog of procedural ape Alang, or add me on wechat (WN8398).

This article has also been compiled at GitHub.com/niumoo/Java… Welcome Star.