I am kite, the public account “ancient time kite”, a not only technology public account, I have been in the app community for many years, mainly Java, Python, React also play 6 slash developer. The Spring Cloud series is complete, and you can check out the full series on my Github. You can also reply “PDF” in the public account to get the full PDF version of my elaborate tutorial.

The biggest advantage of Spring Boot compared to Spring MVC is that it is easier to use and more conventions than configurations. I will not be confused by XML configuration files as I was when I used Spring MVC, and the whole project will be inexplicably unavailable due to a little carelessness in XML configuration.

That’s thanks to the various starters that make up Spring Boot, both officially offered and open-source by third parties. Suffice it to say, almost all the features you want to use can be found. If not, look again.

The procedures for using Spring Boot’s functional components (such as Spring-boot-starter -actuator, Spring-boot-starter -data-redis, etc.) are very simple. In the famous way of putting elephants in refrigerators, There are three steps to complete the use of component functionality:

STEP 1

Import the corresponding package in the POM file, for example:

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

STEP 2

Add the corresponding configuration to the application configuration file. The configuration is specified by the component. You need to view the official documents or related instructions. Some of the more complex components, the corresponding parameters and rules are also more, some may be dozens or hundreds of large.

STEP 3

With the above two steps working, we can use the relevant interfaces provided by the component to develop business functions.

Right? This is a process we practice many times in daily development. So why is Spring Boot so easy to use, what is its internal work mechanism, I don’t know if you have studied.

The following is a demo starter made to understand the implementation mechanism of the Spring Boot component. What does it mean to understand how it works in the future?

  1. When encountering problems, it can help us to have a clue to troubleshoot problems;

  2. It helps us read the source code correctly, where the entry point of the component is, what the configuration properties are, etc.

Start implementing a Spring Boot Starter

Let’s implement a simple starter that doesn’t have any real functionality, just for demonstration purposes.

Before we begin, we need to understand what a Spring boot starter is.

Starter doesn’t actually contain much functional code, and can be thought of as a “connection pack” (a concept I coined myself).

It is first and foremost a package, a collection, that encapsulates the other functional components needed in its own POM file.

And then it’s a connection, which makes a connection between the component it introduces and our project, and saves us the complicated configuration in the middle, and tries to make it as simple as possible to use.

There are four elements to implementing a starter:

  1. The starter named;
  2. Automatic configuration classes for initializing associated beans;
  3. Spring.factories specifies the configuration file for the auto-configuration class.
  4. A custom attribute entity class that declares the application configuration properties of starter;

All right, let’s implement our demo

1. Give your starter a name

That’s the artifactId we referenced in the POM when we used it. There are rules for naming, official rules:

The official starter name format is spring-boot-starter-{name}, for example, spring-boot-starter-actuator mentioned above.

The unofficial starter is named in {name}-spring-boot-starter format. We name our custom starter kite-spring-boot-starter in the POM file.

<groupId>kite.springcloud</groupId>
<artifactId>kite-spring-boot-starter</artifactId>
<packaging>jar</packaging>
<version>1.0 the SNAPSHOT</version>
Copy the code

2. Import the automatic configuration package and other dependent packages

The implementation of starter relies primarily on auto-configuration annotations, so two jars related to auto-configuration are introduced in the POM

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
 <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-autoconfigure</artifactId> </dependency> Copy the code

In addition, other dependent packages will of course be imported.

3. Create the Spring. factories file

Create a file named Spring. factories in the resource/ meta-INF directory. When Spring Boot starts, it looks for all the spring.Factories files in the classpath, runs the auto-loaded classes specified by the configuration inside, and initializes the associated beans in the specified class (one or more).

For example, the configuration information in this example looks like this:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  kite.springcloud.boot.starter.example.KiteAutoConfigure
Copy the code

Before the equal sign is fixed writing method, behind is our custom automatic configuration class, if there are more than one, with English comma separated.

4. Write automatic configuration classes

The auto-configuration class is used to initialize the related beans in the starter. It is the core function of starter.

@Configuration
@ConditionalOnClass(KiteService.class)
@EnableConfigurationProperties(KiteProperties.class)
@Slf4j
public class KiteAutoConfigure {
  @Autowired  private KiteProperties kiteProperties;   @Bean  @ConditionalOnMissingBean(KiteService.class)  @ConditionalOnProperty(prefix = "kite.example",value = "enabled", havingValue = "true")  KiteService kiteService(a){  return new KiteService(kiteProperties);  } } Copy the code

The code is very simple, and the most you can see are annotations.

@configuration is an automatic Configuration class. It is also used for reading Configuration files.

@ ConditionalOnClass (KiteService. Class) :

This auto-configuration class is resolved only if the KiteService class is found in the CLASspath, otherwise it is not resolved.

@ EnableConfigurationProperties (KiteProperties. Class) :

Enable the configuration class.

@bean: instantiates a Bean.

@ ConditionalOnMissingBean (KiteService. Class) :

With @bean, the annotated code block is executed only if there is no Bean in the current context, that is, if there is no instance of a KiteService Bean in the current context, Instantiate an instance of the bean.

@ ConditionalOnProperty:

The annotated code block is executed only when there is a relevant configuration in the application configuration file.

The overall meaning of this class is that the configuration class is resolved when KiteService exists in the classpath, and only exists in the Classpath when the project references the associated JAR package. And if there are no KiteService bean instances in the context, new an instance and pass in the relevant configuration values in the application configuration.

5. Implement the property configuration class

@Data
@ConfigurationProperties("kite.example")
public class KiteProperties {

    private String host;
  private int port; } Copy the code

The configuration class is simple, with only two properties, one host and one port. Configuration parameters are prefixed with kite.example. We’ll see how to declare configuration properties later when we use the starter.

6. Implement related function classes

In fact, strictly speaking, this business function class should not be placed in the starter, but should be placed in a separate JAR package, but the demo is very simple and will be written here.

@Slf4j
public class KiteService {

    private String host;

 private int port;   public KiteService(KiteProperties kiteProperties){  this.host = kiteProperties.getHost();  this.port = kiteProperties.getPort();  }   public void print(a){  log.info(this.host + ":" +this.port);  } } Copy the code

A constructor and a print method.

Pack 7.

Install the starter into the local Maven repository using the maven command

mvn install
Copy the code

It can also be published to your private server via MVN Package deploy

Or publish to a central repository.

Use the starter you just created

Starter has been developed and installed in the local repository, and it’s time to use it in our project.

1. Create a project and reference it in the POM

<dependency>
    <groupId>kite.springcloud</groupId>
    <artifactId>kite-spring-boot-starter</artifactId>
    <version>1.0 the SNAPSHOT</version>
</dependency>
Copy the code

2. Apply the configuration items

Create application.yml with the following configuration:

server:
  port: 3801
kite:
  example:
 enabled: true  It takes effect only when enabled
 host: 127.0. 01.  port: 3801 Copy the code

3. Invoke the service method of KiteService

@RestController
@RequestMapping(value = "use")
public class UseController {

    @Autowired
 private KiteService kiteService;   @GetMapping(value = "print")  public void print(a){  kiteService.print();  } } Copy the code

4. Start the service and access the interface

If you access the /use/print interface, the configuration information is printed in logs

The 2019-05-24 16:45:04. 36687-234 the INFO [nio - 3801 - exec - 1] K.S.B oot. The starter. Example. KiteService: 127.0.0.1:3801Copy the code

How to read other starter source code

Along those lines, let’s look at the official starters structure. Clone Spring Boot from Github. Open with IDEA, you can see the project structure as follows


Spring-boot-starters are the official primary starters, like JDBC, Redis, Security, Web, and so on.

Let’s take spring-boot-starter-data-redis as an example to describe how the official project structure is organized and how the source code should be read in order.

1. Expand redis Starter under spring-boot-Staters. The directory structure is as follows


There is no Java code, just a spring.provides file that reads as follows:

provides: spring-data-redis,lettuce-core
Copy the code

In other words, this project relies on the spring-data-redis and author-core packages, which are referenced in the POM file. The purpose is to tell the consumer that when referring to this package, it does not have to refer to the dependency packages in the provides.

2. Then there is the automatic annotation. All the automatic annotation classes and property configuration classes of Stater are placed under the spring-boot-Autoconfigure project


Spring. factories (” Spring. factories “) This is a lot of content, we will only look at redis related

org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration
Copy the code

It contains three automatic configuration files, and then we find the package by following the configuration


Then you can start reading the code. Other starters have the same structure.

Reference content:

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html#boot-fea tures-custom-starter

Strong man wait, first give a praise bar, always white piao, the body can not bear!

I am kite, public id “ancient Time kite”, I have been working in the application circles for many years, mainly Java, Python, React also play very 6 slash developer. Can add my friends in the public account, into the group of small partners exchange learning, a lot of dachang students are also in the group yo.