1. Introduction

As Spring became bloated, it was born to simplify configuration, out of the box, and integrate quickly. It has become the most popular framework in Java. We usually use Spring Boot to develop web applications. Spring MVC uses the Tomcat servlet container by default because Spring MVC components integrate spring-boot-starter-Tomcat. But now the Undertow servlet container is performing very well. Tomcat can be excluded in the following ways:

Then replace it directly with undertow:

The code doesn’t need to change. This is the benefit of componentization: 1. Pluggable. 2. Customizable. 3. On-demand integration. Why can achieve fast adaptation? Consider this scenario: if a screw on your car wheel breaks, you buy a screw to install yourself. You go to the store and you give the make and location of your car and the owner knows exactly what kind of screws you’re using. That’s the benefit of having standards already set. Without a standard, it’s easy to buy screws that don’t match, and you have to keep trying and trying. This is clearly not what you want. If this standard is imperceptible, then we can communicate more quickly and conveniently. Sometimes you can tell from your girlfriend’s look what she’s up to. So Spring Boot has a “convention over configuration” rule that allows application components to reduce configuration and complexity. Therefore, you should also consider how your Starter can achieve the above convenience when developing a custom Spring Boot Starter.

2. Some Spring Boot conventions

The design of a component must have standards and rules. Spring Boot Starter is no exception. Let’s look at some general practices.

2.1 Naming Style

If you’re going to have a baby, the first thing you need is a name. The name marks you and your lover’s bloodline, certainly not from next door Lao Wang’s surname, will certainly attract strange eyes. In Maven, groupId stands for last name and artifactId stands for first name. Spring Boot also has a suggested name. GroupId do not use the official org.SpringFramework. boot but use your own unique groupId. For artifactId naming, the unofficial Starter naming format is xxxx-spring-boot-starter, for example, mybatis-spring-boot-starter. The official starter follows spring-boot-starter- XXXX, such as spring-boot-starter-undertow mentioned above. Many open source starter writers ignore this convention and appear unprofessional.

3. Customize a Starter

Next we build a custom third-party SMS starter named SMS-spring-boot-starter. There are some details that need to be explained as I write. Here is a template for the samples and test modules omitted:

Based on the above, we have established the following projects:

3.1 the SMS – spring – the boot

An important part of smS-spring-boot building a project is dependency management. So it is necessary to introduce BOM. All modules that manage the starter, all dependencies of the starter, and even SMS-spring-boot-autoconfigure are managed by SMS-spring-boot.

3.2 the SMS – spring – the boot – autoconfigure

This module is mainly used to define configuration parameters and automatically configure exposed functions (typically abstract interface Spring beans).

3.2.1 Setting Parameters

The general configuration parameters are in the Application.yml of Spring Boot. We will define a prefix identifier as a parameter for namespace isolation of components. The corresponding component defines a XXXXProperties to automatically assemble these parameters. The autowage mechanism is based on the @ConfigurationProperties annotation. Be sure to explicitly declare your configured prefix. Our SMS-spring-boot will do the following configuration:

The above takes the SMS function of Aliyun as an example for configuration. In future use, you only need to add the above configuration of SmsProperties in application.yml:

You can also verify SmsProperties if you have integrated with the Spring Boot verification library. Careful Java developers when configuring application.yml will notice that parameter configurations are described as follows:

It’s as easy to understand what this configuration does as Java annotations, which are actually generated by Java annotations. You need to rely on

The dependency then extracts the comments for the SmsProperties member property to generate a spring-configuration-metadata.json file, which is the metadata file for the configuration description. Spring Boot also imposes some rules on comments:

  • Don’t start your description with “The” or “A”.
  • For Boolean types, use “Whether” or” Enable “to start the description.
  • For collection based types, use “comma-Separated List”
  • If the default time unit is not the same as a millisecond, use java.time.Duration instead of long to describe the default unit, for example, “seconds will be used if no Duration suffix is specified.”
  • Do not provide defaults in the description unless you must determine them at run time.

I personally suggest that the description should be in English as much as possible.

3.2.2 Configuring the Auto Exposure Interface

After getting the configuration, the next step is to initialize our functional interface according to the configuration. We will abstract a SMS sending interface SmsSender and design the function according to the SDK of the SMS provider. Note that the autoconfigure module’s dependencies are almost always non-transitive. That is, coordinate dependent configuration optional is true. After the implementation of the functional interface we will write an automatic configuration class SmsAutoConfiguration. In addition to the @Configuration annotation, @ConfigurationProperties will help us load in our Configuration class SmsProperties. We then declare the functional interfaces we need to expose to the Spring Boot application as Spring Beans. Sometimes we can also control SmsAutoConfiguration or SmsSender by some condition, such as whether a condition is loaded or different SmsSender is loaded. You can see this when you look at Redis-Starter sometime, which instantiates different client links depending on luttuce, Redisson, and Jedis. This is done using the @Conditional series of annotations, which you can study if you have time. Our SmsAutoConfiguration declaration is as follows:

3.2.3 Active and passive effectiveness

Starter can be integrated into an application in two ways. From an application perspective, there are two kinds:

  • One is active. When the starter is integrated into the Spring Boot application, you need to actively declare that the starter is enabled to take effect, even if you are fully configured. The @import annotation will be used here. Tag this annotation with your custom @enable annotation:

    We can use SMS by marking this annotation into the Spring Boot application.

  • Another passive effect is captured by the application when the starter component is integrated into the Spring Boot application. The Java-like SPI mechanism will be used here. New Meta-INF/Spring. factories under the autoconfigure resource package and write the SmsAutoConfiguration fully qualified name.

Multiple configuration classes are separated by commas, and newlines use backslashes.

3.3 the SMS – spring – the boot – the starter

The module is an empty JAR. Its sole purpose is to provide the necessary dependencies to use starter. You can think of it as the only entry point to integrate the starter feature. Don’t make assumptions about projects that add initiators. If the dependent libraries you automatically configure typically require additional initiators, mention them as well. If the number of optional dependencies is high, it may be difficult to provide an appropriate set of default dependencies, because you should avoid including unnecessary dependencies for use of typical libraries. In other words, you should not include optional dependencies. Either way, your starter must directly or indirectly reference the core Spring Boot starter (spring-boot-starter) (you don’t need to add it if your starter depends on another starter). If you create projects using only custom initiators, the core functionality of Spring Boot is implemented through the existence of the core initiators. Our SMS-spring-boot-starter is just the following POM:

At this point, our entire SMS Starter development is complete.

4. To summarize

Custom starter is of great help to our project componentization and modularization. It is also a feature of Spring Boot. I believe that you are already stupid enough to try it through xiao Pang’s introduction, so start writing one as soon as possible. You can like it and follow it if you find it useful.

Demo address: gitee.com/felord/sms-…

Pay attention to the public number: code nongxiao Pangge, get more information