Handwritten custom springboot-starter, feel the charm and principle of the framework

I. Introduction

Springboot's automatic configuration principle is often asked in interviews, and I can't remember it even after reading it. It is better to write a starter by hand to deepen my memory.
After reading it, I found that most of the starters are based on this principle, and the practice will be memorable.
Core idea: 约定大于配置.

2. Preliminary study on the principle of starter startup

Let's take a look at how the official website starteris designed, just write one like this!

We Ctrlclicked <artifactId>spring-boot-starter-web</artifactId>to enter the internal pom, and we found that there is a

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
  <version>2.5.3</version>
  <scope>compile</scope>
</dependency>

CtrlClick here <artifactId>spring-boot-starter</artifactId>to enter the internal pom of the starter:
we found that this package dependency is what we will do later:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-autoconfigure</artifactId>
  <version>2.5.3</version>
  <scope>compile</scope>
</dependency>

insert image description here

We can now create two projects:

  • spring-boot-starter (starter)
  • spring-boot-starter-autoconfigure (automatic configuration package)

The editor saw the reminder written by the official, you can name it according to the official website, don't learn from the editor! !

You should make sure to provide an appropriate namespace for your launcher. Do not start the module name spring-boot with . even if you use a different Maven groupId. We may provide official support for your auto-configured content in the future.
As a rule of thumb, you should name your composite modules after the enabler. For example, suppose you are creating a starter for "acme" and you name the auto-configuration module acme-spring-boot and the starter acme-spring-boot-starter. If you have only one module combining the two, name it acme-spring-boot-starter.

3. Project construction

1. Create a new blank project

insert image description here
Enter the overall project name
insert image description here
and create two new ones in the blank project, which can be created separately here. The editor here is the same as Raytheon, so we will not create separate projects! !

insert image description here

2. Create a new maven project

insert image description here
Package name and name:

insert image description here

3. Create a new springboot project

insert image description here

4. Project structure

Delete all the useless ones here! ! can not delete
insert image description here

4. Configuration

1. Introduce your own autoconfigure dependencies in the starter project

It is the setting of building the project above

<dependencies>
    <dependency>
        <groupId>com.wang</groupId>
        <artifactId>spring-boot-autoconfigure</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
</dependencies>

insert image description here

2. spring-boot-autoconfigure pom configuration

<properties>
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>${spring-boot.version}</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.24</version>
    </dependency>
</dependencies>

Or delete the useless things, the rest is as follows:

insert image description here

Five, write autoconfigure project

1. Configure a bean

First delete the automatic startup class, we don’t need it, create a new bean
in spring-boot-autoconfigurethe project, and don’t need to let this bean be in the container at this time, we write a self-configuration to let it automatically add to the container.
This is the idea of ​​automatic configuration

/**
 * 这里不需要让在容器中,我们写一个自己配置,让他自动加入到容器中
 * @author wangzhenjun
 * @date 2022/10/14 16:26
 */
public class HelloService {

    @Autowired
    private MyProperties myProperties;

    public String HelloWord (String username){
        return myProperties.getPrefix() + username + myProperties.getSuffix();
    }
}

2. Write a configuration file

Here, in order to obtain the attribute values ​​in the configuration file, most of the springboot automatic configuration source code is written in a configuration file, and others can be obtained according to the beginning 属性和值! !


/**
 * @author wangzhenjun
 * @date 2022/10/14 16:28
 */
@Data
@ConfigurationProperties("wang.name")
public class MyProperties {

    private String prefix;
    private String suffix;
}

3. Write auto-configuration

import com.wang.springbootautoconfigure.properties.MyProperties;
import com.wang.springbootautoconfigure.service.HelloService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author wangzhenjun
 * @date 2022/10/14 16:33
 */
@Configuration
//没有这个bean的时候才会生效
@ConditionalOnMissingBean(HelloService.class)
// 加载配置文件,让它成为容器中的bean
@EnableConfigurationProperties(MyProperties.class)
public class ServiceAutoConfiguration {
	
	
	/**
	 * 把刚刚写的服务,加入到容器中
	 */
    @Bean
    public HelloService helloService (){
    	
        return new HelloService();
    }
}

The main thing is conditionto add a few annotations to complete beanwhether to add to the container:
Commonly used:

  • @ConditionalOnClass
  • @ConditionalOnMissingClass
  • @ConditionalOnBean
  • @ConditionalOnMissingBean
  • @ConditionalOnProperty
    insert image description here

4. New spring.factories

We see that the automatic configuration in the source code is to get and load from this file, so we imitate this and create a new one, so that we can scan and add it to the container! !

insert image description here

If it is springboot2.7 or above:
folder name: META-INF.spring
file name:org.springframework.boot.autoconfigure.AutoConfiguration.imports

insert image description here
Just write the full class name in it!

5. Pack

First spring-boot-autoconfigurepackage it to the local library, and then package it spring-boot-starter, the order must be there, otherwise the former package cannot be found! !

insert image description here

6. Test

We are testing a new project, and the editor of the new project will not lead you to build it!

1. Import our starter dependencies

<dependency>
    <groupId>com.wang</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

2. Add configuration file

wang:
 name:
  prefix: hello
  suffix: 886

insert image description here

3. Create a new controller test class

@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    private HelloService helloService;

    @GetMapping("/starter")
    public String starter(){

        return helloService.HelloWord("tom");
    }
}

4. Test access

The visit was successful, but there are garbled characters in Chinese. I can't find a solution. If you understand, please leave a message to let me know! !
Once the main process is cleared, you can slowly understand the charm of automatic configuration!
The overall process should be like this:

Introduce starter --- xxxAutoConfiguration --- put components in the container ---- bind xxxProperties ---- configuration items

insert image description here
The Chinese is garbled, maybe there is no servlet, if you understand, please leave a message to tell me the solution, thank you! !

insert image description here

7. Summary

Once you see it, you will lose it once you do it! Everyone still has to do their own practice, don't be too high-minded, so that you will gain something, it's just that 约定大于配置+SPI发现机制!
There are also some annotations that often appear in the source code, you can write the starter yourself after remembering it!

Guess you like

Origin blog.csdn.net/weixin_47367099/article/details/127458597