brief introduction
starter is a service (or plug-in)
- So that developers using a function do not need to pay attention to the processing of various dependent libraries and specific configuration information. Spring Boot automatically finds the required beans through the classes under the classpath path and weaves them into beans.
- In short: component development thinking, improve code reusability and avoid repeated wheel making!!
Knowledge points
- The naming method of the project is [name] - spring boot starter (the official naming method is spring boot starter - [name])
- In POM Add the dependencies required by starter in XML
- Create starter related classes (at least one autoconfiguration class)
- Create a META-INF folder (srping.factories) under the resource folder
actual combat
Establish a swagger spring boot starter to simplify the process of configuring swagger when building a project
General directory structure

General structure
The naming method of swagger spring boot starter is consistent, which also indicates that this project is not an official spring boot project
Configure POM xml
Add spring core development package and swagger dependency
copy<?xml version="1.0" encoding="UTF-8"?> <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.4.13</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.mobaijun</groupId> <artifactId>swagger-spring-boot-starter</artifactId> <version>2.4.13</version> <name>swagger-spring-boot-starter</name> <inceptionYear>2022</inceptionYear> <description>swagger-spring-boot-starter</description> <url>https://github.com/mobaijun/swagger-spring-boot-starter</url> <!-- Version information --> <properties> <java.version>1.8</java.version> <swagger-ui.version>3.0.3</swagger-ui.version> <swagger.version>3.0.0</swagger.version> <nexus-staging-maven-plugin.version>1.6.8</nexus-staging-maven-plugin.version> <maven-release-plugin.version>3.0.0-M1</maven-release-plugin.version> <maven-gpg-plugin.version>1.6</maven-gpg-plugin.version> <maven-source-plugin.version>3.1.0</maven-source-plugin.version> <maven-javadoc-plugin.version>3.1.1</maven-javadoc-plugin.version> </properties> <!-- licence --> <licenses> <license> <name>Apache License, Version 2.0</name> <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url> <distribution>repo</distribution> <comments>A business-friendly OSS license</comments> </license> </licenses> <!-- GitHub issues --> <issueManagement> <system>GitHub Issues</system> <url>https://github.com/mobaijun/swagger-spring-boot-starter/issues</url> </issueManagement> <scm> <url>https://github.com/mobaijun/swagger-spring-boot-starter</url> <connection>https://github.com/mobaijun/swagger-spring-boot-starter.git</connection> <developerConnection>https://github.com/mobaijun</developerConnection> </scm> <!-- personal information --> <developers> <developer> <name>mobaijun</name> <email>wljmobai@gmail.com</email> <url>https://www.mobaijun.com</url> </developer> </developers> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <!-- swagger 3.0 Core dependency package --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>${swagger.version}</version> </dependency> <!-- swagger-ui --> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <!--When quoting, please maven Central warehouse search 2.X Latest version number--> <version>${swagger-ui.version}</version> </dependency> <dependency> <!-- Core dependency package --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency> </dependencies> </project>
- Dependency graph

- Core development package

Core autoconfiguration
Explanation:
Auto configuration, spring boot has an @ EnableAutoConfiguration annotation, which reads spring The class specified under EnableAutoConfiguration in the factories file is used to initialize all methods added with @ bean under the specified class and initialize this bean
Property configuration class
copypackage com.mobaijun.swagger.prop; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; /** * Software: IntelliJ IDEA 2021.3.2 * ClassName: SwaggerProperties * Class description: Swagger configuration read class * * @author MoBaiJun 2022/3/12 17:24 ---- https://www.mobaijun.com */ @ConfigurationProperties(SwaggerProperties.PREFIX) @EnableConfigurationProperties(SwaggerProperties.class) public class SwaggerProperties { /** * identification */ public static final String PREFIX = "swagger"; }
Code Description:
Use the @ ConfigurationProperties annotation to set the prefix in application Through swagger. In YML XXX = to set.
Property configuration class
copypackage com.mobaijun.swagger.config; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Configuration; /** * Software: IntelliJ IDEA 2021.3.2 * ClassName: SwaggerConfiguration * Class description: * * @author MoBaiJun 2022/4/26 14:57 */ @Configuration @ConditionalOnProperty(name = "swagger.enable", matchIfMissing = true) public class SwaggerConfiguration { }
Auto configuration class
copypackage com.mobaijun.swagger.config; import com.google.common.collect.Lists; import com.mobaijun.swagger.prop.SwaggerProperties; import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.ApiKey; import springfox.documentation.service.AuthorizationScope; import springfox.documentation.service.Contact; import springfox.documentation.service.SecurityReference; import springfox.documentation.service.SecurityScheme; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger.web.ApiKeyVehicle; import java.util.Collections; import java.util.List; /** * Software: IntelliJ IDEA 2021.3.2 * ClassName: SwaggerConfig * Class description: swagger configuration class * * @author MoBaiJun 2022/4/26 9:09 */ @Configuration @Import({SwaggerConfiguration.class}) public class SwaggerAutoConfiguration { private final Logger log = LoggerFactory.getLogger(SwaggerAutoConfiguration.class); @Bean @ConditionalOnMissingBean public SwaggerProperties swaggerProperties() { return new SwaggerProperties(); } /** * # Common notes * 1,@Api: Used in the controller class to describe the API interface * 2,@ApiOperation: Describe interface method * 3,@ApiModel: Description object * 4,@ApiModelProperty: Describe object properties * 5,@ApiImplicitParams: Describe interface parameters * 6,@ApiResponses: Describe interface response * 7,@ApiIgnore: Ignore interface methods * 8,Access address: http://localhost:8003/swagger-ui/index.html#/ * 9,doc Document access address: http://localhost:8003/doc.html */ @Bean public Docket createRestApi(SwaggerProperties swaggerProperties) { log.info("============================ Swagger Api Build successful ============================"); return new Docket(DocumentationType.SWAGGER_2) // Enable swagger / production environment shutdown .enable(swaggerProperties.getEnable()) // server address .host(swaggerProperties.getHost()) // Setting the name of the Docket can realize multiple dockets and grouping .apiInfo(apiInfo(swaggerProperties)) .select() // withMethodAnnotation scans all API s containing (@ ApiOperation), which is more flexible in this way .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) // The regular matching request path is allocated to the current packet and all interfaces .paths(PathSelectors.any()) .build() // Group name .groupName(swaggerProperties.getGroupName()) // Global application of authorization information .securityContexts(securityContexts()) // Authorization information setting, necessary header token and other authentication information .securitySchemes(apiKeys()); } /** * API The top half of the page displays information */ private ApiInfo apiInfo(SwaggerProperties sp) { return new ApiInfoBuilder() // title .title(sp.getTitle()) // explain .description(sp.getDescription()) // Official website .termsOfServiceUrl(sp.getTermsOfServiceUrl()) // licence .license(sp.getLicense()) // License address .licenseUrl(sp.getLicenseUrl()) // Author information .contact(new Contact( // author sp.getContact().getAuthor(), // Blog address sp.getContact().getUrl(), // mailbox sp.getContact().getEmail())) // edition .version(sp.getVersion()) .build(); } /** * Set authorization information */ private List<SecurityScheme> apiKeys() { return Lists.newArrayList(new ApiKey(swaggerProperties().getAuthorization().getHeader(), swaggerProperties().getAuthorization().getToken(), ApiKeyVehicle.HEADER.getValue())); } /** * Global application of authorization information */ private List<SecurityContext> securityContexts() { return Lists.newArrayList(SecurityContext.builder() .securityReferences(defaultAuth()) .forPaths(PathSelectors.regex(swaggerProperties().getAuthorization().getAuthRegex())) .build()); } /** * Configure the default global authentication policy; In the returned SecurityReference, the reference is the name in the ApiKey object. Global authentication can only be enabled if it is consistent */ private List<SecurityReference> defaultAuth() { AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; authorizationScopes[0] = authorizationScope; return Collections.singletonList(SecurityReference.builder() .reference(swaggerProperties().getAuthorization().getHeader()) .scopes(authorizationScopes).build()); } }
Extended annotation
copypackage com.mobaijun.swagger.annotation; import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; import com.mobaijun.swagger.config.SwaggerAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration; import springfox.documentation.swagger2.annotations.EnableSwagger2; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author MoBaiJun 2022/4/26 9:26 */ @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration @EnableSwagger2 @EnableKnife4j @Import({BeanValidatorPluginsConfiguration.class, SwaggerAutoConfiguration.class}) public @interface EnableSwagger { }
Source address: mobaijun/swagger-spring-boot-starter (github.com)
Registration configuration
Under src/main/resource, create a new meta-info / spring Factories file. The settings are as follows:
copyorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.mobaijun.swagger.config.SwaggerConfiguration
If there are multiple, they can be separated by commas, as follows:
copy# example org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration
Packaging and publishing
copy$ mvn clean install
Quick start
Because the starter has been uploaded to the maven central warehouse, it can be directly copied and used in your project
copy<dependency> <groupId>com.mobaijun</groupId> <artifactId>swagger-spring-boot-starter</artifactId> <version>2.4.13</version> </dependency>
Configuration description
copyserver: port: 8002 swagger: # Open swagger enable: true # title title: spring-boot-swagger-demo # Service address host: localhost:${server.port} # edition version: 1.0.0 # Group name group-name: R & D department # describe description: This is a demo # Program address terms-of-service-url: https://localhost:${server.port}/index.html # Author information configuration contact: # Author information author: mobaijun # Blog address or official website address url: https://www.mobaijun.com # Configure mailbox email: mobaijun8@163.com
For details, please refer to the project source code readme MD document description

summary
No matter what the architecture of the project is, we should pursue the reusability of the code. In particular, some reusable functions, such as log, cache, result api, database and other operations, can be extracted and made into components. When developing new projects in the future, we can directly introduce dependency, so that developers can focus more on business development. We recommend that you develop a starter suitable for your own business as the company's infrastructure, After all, repeated wheel making is meaningless, and it is terrible to quote private bags for maintenance!!!