As we all know, Spring is very powerful, but there are some drawbacks. For example, we need to manually configure a large number of parameters, there is no default value, we need to manage a large number of jar packages and their dependencies.

In order to improve the development efficiency of the Spring project and simplify some configurations, Spring officially introduced SpringBoot.

Of course, there are other reasons for the introduction of SpringBoot, which I will not describe too much here.

This article focuses on SpringBoot’s starter mechanism, because it’s so important.

Before SpringBoot came out, we used Spring development projects. If the program needs to connect to the database, we will generally use ORM frameworks such as Hibernate or Mybatis, here I take Mybatis as an example, the specific operation steps are as follows:

Of course, some friends may point it out, don’t you still need to introduce database driver packages?

It does need to be introduced, but there are many database drivers, such as: mysql, oracle, sqlserver, which does not belong to the mybatis category, and users can introduce them separately according to the actual situation of the project.

If the program just needs to connect to the database this one function is fine, follow the above steps to basically meet the needs. However, connecting to the database may only be one part of a huge project system, and the actual project is often more complex and needs to introduce more functions, such as: connecting redis, connecting mongodb, using rocketmq, using excel functions, and so on.

If these functions are introduced, the above steps need to be repeated again, and the workload has increased invisibly, and there are many repetitive tasks.

In addition, there is still a problem, every time to find a suitable version in maven, if which time to find the mybatis .jar package and mybatis-spring .jar package version is not compatible, the program will not have a problem?

SpringBoot introduced the starter mechanism to solve these two problems.

Let’s first look at how the mybatis-spring-boot-starter .jar is defined.

It can be seen that its META-INF directory contains only:

Note that there is no single line of code.

Let’s focus on pom .xml, because there is no important information in this jar bag except this

As you can see from the above, some jar packages are introduced into the pom .xml file, in addition to the introduction of spring-boot-starter, which focuses on mybatis-spring-boot-autoconfigure.

We find the mybatis-spring-boot-autoconfigure .jar file and open this file.

It contains the following files:

spring-configuration-metadata.json and additional-spring-configuration-metadata.json have similar functions, when we enter spring in the applicationContext.properties file, the following configuration information will automatically appear to choose from, which is this function.

A question from the soul: What is the difference between these two documents?

A: If the spring-boot-configuration-processor package is introduced in the pom .xml, spring-configuration-metadata.json is automatically generated.

If you need to manually modify the metadata inside, you can edit it in additional-spring-configuration-metadata.json, and eventually the metadata in the two files will be merged together.

The MybatisProperties class is a property entity class:

You can see that many of the properties needed for Mybatis initialization are here, equivalent to a JavaBean.

Here’s a look at the MybatisAutoConfiguration code:

This class is a Configuration class, which defines many beans, the most important of which is the bean instance of SqlSessionFactory, which is the core function of Mybatis, which uses it to create SqlSession and perform CRUD operations on the database.

In addition to this, the MybatisAutoConfiguration class includes:

These annotations are accessibility features that determine whether Configuration is valid or not, but these annotations are not required.

Next, focus on what the spring.factories file contains:

There is only one line of configuration, that is, the key is EnableAutoConfiguration and the value is MybatisAutoConfiguration.

Okay, so much has been introduced, now let’s summarize,

Several elements of the starter are shown in the following figure: So, what steps do you need to write a starter?

Let’s try to follow these four steps, write a starter ourselves to see if it succeeds, and verify that the summary is correct.

The name of the project is id-generate-starter, note that in order to facilitate my renaming of the project, it should have been called id-generate-spring-boot-starter, as shown in the following figure:

The pom .xml file is defined as follows:

We see that it only introduces id-generate-spring-boot-autoconfigure. Of course, if necessary, you can also introduce multiple autoconfigures or multiple other jar packages or more.

Also for the convenience of my renaming the project, it was originally called id-generate-spring-boot-autoconfigure, as shown in the following figure:

The project includes five key files: pom.xml, spring.factories, IdGenerateAutoConfiguration, IdGenerateService and IdProperties, which we will take a look at one by one.

Start with the pom.xml

As we can see, this file is relatively simple to introducing:

Take a look at the spring.factories file in focus:

It contains only one line of configuration, where key is EnableAutoConfiguration and value is IdGenerateAutoConfiguration.

Let’s focus on IdGenerateAutoConfiguration

The class is a @Configuration annotation tag used in order to configure the class, which takes effect @ConditionalOnClass the annotation detects a .class containing IdProperties. And annotations using @EnableConfigurationProperties are automatically injected into instances of IdProperties.

In addition, the most critical point is that a bean instance of idGenerateService is created in this class, which is the essence of automatic configuration.

Look at IdGenerateService

We can see that it is a normal class that does not even use @Service annotation, which has a genetic method that dynamically generates ids based on the value of workId and random numbers.

Finally, take a look at IdProperties

It is a configuration entity class that contains the relevant configuration files. Using @ConfigurationProperties annotation, the parameter values in the application.properties file with the same parameter names as those in IdProperties are automatically injected into the IdProperties object.

This project is mainly used for testing.

The project contains: pom.xml, application.properties, Application and TestRunner files.

Take a look at the pom .xml file first

Since only the id generation function just defined is tested, only the id-generate-spring-boot-starter jar package is introduced.

application.properties configuration resource file

There is only one line of configuration, as we currently only need this one parameter in IdProperties.

Application is a test program startup class

Quite simply, it’s just a normal springboot startup class

TestRunner is our test class

It implements the ApplicationRunner interface, so the run method of the class is called when springboot starts.

Well, all the custom starter code and test code are ready. Next, run the main method of the Application class.

Running result:

Perfect, validation succeeded.

Next, let’s analyze the underlying implementation principle of the starter.

Through the above writing their own starter example, I believe that everyone’s understanding of the starter has gone further, and now let’s take a look at how the bottom layer of the starter is implemented.

The id-generate-starter .jar is actually an empty project that relies on the id-generate-autoconfiguration.jar.

The id-generate-starter .jar is an entrance, and we give him a more elegant name: façade mode, through which other business systems must pass to introduce corresponding functions.

Let’s focus on the id-generate-autoconfiguration.jar

The core content of the jar package is: IdGenerateConfiguration, in this configuration class creates the IdGenerateService object, IdGenerateService is the specific function we need to automatically configure.

Next is the most important question:
Why does IdGenerateConfiguration load automatically?

Remember when we defined the spring.factories file as not?

It contains only one line of configuration, where key is EnableAutoConfiguration and value is IdGenerateAutoConfiguration.

To understand this process, start with the @SpringBootApplication annotations of the Application class:

As can be seen from the above, the annotation contains @EnableAutoConfiguration annotations.

@EnableAutoConfiguration annotation introduces the AutoConfigurationImportSelector class.

A key method of the selectImports method of the class:

Here’s the secret that starter can automatically configure.

In addition, some friends may have doubts when they look at the springboot starter defined by others.

Let’s look at druid-spring-boot-starter

The druid-spring-boot-starter defined by alibaba only has xxx-spring-boot-starter .jar files, and no xxx-spring-boot-autoconfigure .jar files.

Look again at spring-boot-starter-jdbc:

What’s even more amazing is that there is not even a pom .xml in this document, and the face is confused…

Am I wrong?

A: Not really.

SpringBoot’s principle is that conventions take precedence over configuration.

Judging from the internal null implementation of spring-boot-starter-jdbc, its convention is to distinguish xxx-spring-boot-starter .jar from xxx-spring-boot-autoconfigure .jar. Personally, alibaba is not well defined, and does not follow the conventions of springboot, although the function is not affected. (Welcome to discuss this place together)

And why doesn’t springboot-boot-starter-jdbc even have a pom .xml file?

Does it not need to rely on xxx-spring-boot-autoconfigure .jar file?

Because springboot puts all the auto-configured classes under the spring-boot-autoconfigure.jar: The spring.factories file is as follows: SpringBoot manages autoconfiguration centrally without having to traverse from various subpackages, which I personally think is to find efficiency.

Let’s take a final look at spring-cloud-starter-openfegin and see that it follows the principles we say.

In addition to this, there is a principle to mention by the way.

The names of the SpringBoot and SpringCloud family definition jar packages are:

And our own project-defined jar should be:

If this article is helpful to you, or inspired, help scan the QR code to pay attention to it, your support is the biggest motivation for me to keep writing.

Ask for one click and three links: like, forward, watching.

Pay attention to the public number: [Su San said technology], reply in the public account: interview, code artifact, development manual, time management has excellent fan benefits, and reply: Jia Qun, you can communicate and learn with the seniors of many BAT manufacturers.