SpringBoot如何自定义starter?
Spring Boot已经内置了127个场景启动器,基本上满足大部分的使用场景,但是有时候也会存在需要自定义starter的场景,如何自定义一个starter呢?其实也很简单,这里简单介绍如何自定义的关键步骤。
创建starter工程
首先创建一个自定义starter工程,除了spring官方的starter之外,第三方的starter一般命名规则遵循*-spring-boot-starter
的原则,引入相应依赖,此处只引入满足条件最小依赖,也可以根据实际场景引入,注意maven的依赖传递原则,不要和外部的冲突,解决好依赖关系。
项目工程:demo-spring-boot-starter
<?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.6.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.starsray</groupId>
<artifactId>demo-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo-spring-boot-starter</name>
<description>demo-spring-boot-starter</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
创建自动配置类
spring boot中starter在项目启动时是否被加载,需要创建一个类来标明,一般来说只要命名是xxxAutoConfiguration
,那就表明这是一个自动配置类。
一般一个自动配置类里面都会伴随着类似xxxProperties
的配置文件类作为参数被加载,通过注解@EnableConfigurationProperties({A.class,B.class,...})
来开启绑定,是否满足加载条件可以使用SpringBoot提供的@Conditionxxx
系列注解来按需加载,这些类里面的属性一般都和项目配置文件的application.yml
直接绑定,命名语法支持松散绑定。
package com.starsray.starter;
import com.starsray.starter.config.DemoConfig;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
/**
* 演示自动配置
*
* @author starsray
* @date 2021/11/20
*/
@Configuration
@EnableConfigurationProperties(DemoConfig.class)
public class DemoAutoConfiguration {
@Resource
private DemoConfig demoConfig;
@PostConstruct
public void run() {
System.out.printf("demo starter ---> %s%n", demoConfig.getName());
}
}
配置类DemoConfig
package com.starsray.starter.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 演示配置
*
* @author starsray
* @date 2021/11/20
*/
@Configuration
@ConfigurationProperties(prefix = "demo")
public class DemoConfig {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
配置加载信息
接下来最关键的一步,starter启动是否能被Spring Boot加载到,就要做此项配置。
在resources目录下创建META-INF文件夹,创建spring.factories
文件,内容如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.starsray.starter.DemoAutoConfiguration
这句话是告诉spring boot在启动时要加载这个组件的位置。
项目启动过程中,Spring Boot会扫描classpath下META-INF文件夹中spring.factories
文件的配置项,加载对应的starter。
创建测试项目
项目名称:demo-web
pom引入自定义starter
<!--引入自定义starter-->
<dependency>
<groupId>com.starsray</groupId>
<artifactId>demo-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
添加配置,测试配置项是否生效,在application.yml中添加配置。
demo:
name: demo config
启动项目
/opt/develop/jdk1.8.0_301/bin/java -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -javaagent:/opt/apps/com.jetbrains.intellij-idea-ultimate/files/lib/idea_rt.jar=46683:/opt/apps/com.jetbrains.intellij-idea-ultimate/files/bin -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dfile.encoding=UTF-8 -classpath /opt/develop/jdk1.8.0_301/jre/lib/charsets.jar:/opt/develop/jdk1.8.0_301/jre/lib/deploy.jar:/opt/develop/jdk1.8.0_301/jre/lib/ext/cldrdata.jar:/opt/develop/jdk1.8.0_301/jre/lib/ext/dnsns.jar:/opt/develop/jdk1.8.0_301/jre/lib/ext/jaccess.jar:/opt/develop/jdk1.8.0_301/jre/lib/ext/jfxrt.jar:/opt/develop/jdk1.8.0_301/jre/lib/ext/localedata.jar:/opt/develop/jdk1.8.0_301/jre/lib/ext/nashorn.jar:/opt/develop/jdk1.8.0_301/jre/lib/ext/sunec.jar:/opt/develop/jdk1.8.0_301/jre/lib/ext/sunjce_provider.jar:/opt/develop/jdk1.8.0_301/jre/lib/ext/sunpkcs11.jar:/opt/develop/jdk1.8.0_301/jre/lib/ext/zipfs.jar:/opt/develop/jdk1.8.0_301/jre/lib/javaws.jar:/opt/develop/jdk1.8.0_301/jre/lib/jce.jar:/opt/develop/jdk1.8.0_301/jre/lib/jfr.jar:/opt/develop/jdk1.8.0_301/jre/lib/jfxswt.jar:/opt/develop/jdk1.8.0_301/jre/lib/jsse.jar:/opt/develop/jdk1.8.0_301/jre/lib/management-agent.jar:/opt/develop/jdk1.8.0_301/jre/lib/plugin.jar:/opt/develop/jdk1.8.0_301/jre/lib/resources.jar:/opt/develop/jdk1.8.0_301/jre/lib/rt.jar:/home/starsray/IdeaProjects/custom-starter/demo-web/target/classes:/home/starsray/.m2/repository/org/springframework/boot/spring-boot-starter-web/2.6.0/spring-boot-starter-web-2.6.0.jar:/home/starsray/.m2/repository/org/springframework/boot/spring-boot-starter/2.6.0/spring-boot-starter-2.6.0.jar:/home/starsray/.m2/repository/org/springframework/boot/spring-boot/2.6.0/spring-boot-2.6.0.jar:/home/starsray/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.6.0/spring-boot-autoconfigure-2.6.0.jar:/home/starsray/.m2/repository/org/springframework/boot/spring-boot-starter-logging/2.6.0/spring-boot-starter-logging-2.6.0.jar:/home/starsray/.m2/repository/ch/qos/logback/logback-classic/1.2.7/logback-classic-1.2.7.jar:/home/starsray/.m2/repository/ch/qos/logback/logback-core/1.2.7/logback-core-1.2.7.jar:/home/starsray/.m2/repository/org/slf4j/slf4j-api/1.7.32/slf4j-api-1.7.32.jar:/home/starsray/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.14.1/log4j-to-slf4j-2.14.1.jar:/home/starsray/.m2/repository/org/apache/logging/log4j/log4j-api/2.14.1/log4j-api-2.14.1.jar:/home/starsray/.m2/repository/org/slf4j/jul-to-slf4j/1.7.32/jul-to-slf4j-1.7.32.jar:/home/starsray/.m2/repository/jakarta/annotation/jakarta.annotation-api/1.3.5/jakarta.annotation-api-1.3.5.jar:/home/starsray/.m2/repository/org/springframework/spring-core/5.3.13/spring-core-5.3.13.jar:/home/starsray/.m2/repository/org/springframework/spring-jcl/5.3.13/spring-jcl-5.3.13.jar:/home/starsray/.m2/repository/org/yaml/snakeyaml/1.29/snakeyaml-1.29.jar:/home/starsray/.m2/repository/org/springframework/boot/spring-boot-starter-json/2.6.0/spring-boot-starter-json-2.6.0.jar:/home/starsray/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.13.0/jackson-databind-2.13.0.jar:/home/starsray/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.13.0/jackson-annotations-2.13.0.jar:/home/starsray/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.13.0/jackson-core-2.13.0.jar:/home/starsray/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.13.0/jackson-datatype-jdk8-2.13.0.jar:/home/starsray/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.13.0/jackson-datatype-jsr310-2.13.0.jar:/home/starsray/.m2/repository/com/fasterxml/jackson/module/jackson-module-parameter-names/2.13.0/jackson-module-parameter-names-2.13.0.jar:/home/starsray/.m2/repository/org/springframework/boot/spring-boot-starter-tomcat/2.6.0/spring-boot-starter-tomcat-2.6.0.jar:/home/starsray/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/9.0.55/tomcat-embed-core-9.0.55.jar:/home/starsray/.m2/repository/org/apache/tomcat/embed/tomcat-embed-el/9.0.55/tomcat-embed-el-9.0.55.jar:/home/starsray/.m2/repository/org/apache/tomcat/embed/tomcat-embed-websocket/9.0.55/tomcat-embed-websocket-9.0.55.jar:/home/starsray/.m2/repository/org/springframework/spring-web/5.3.13/spring-web-5.3.13.jar:/home/starsray/.m2/repository/org/springframework/spring-beans/5.3.13/spring-beans-5.3.13.jar:/home/starsray/.m2/repository/org/springframework/spring-webmvc/5.3.13/spring-webmvc-5.3.13.jar:/home/starsray/.m2/repository/org/springframework/spring-aop/5.3.13/spring-aop-5.3.13.jar:/home/starsray/.m2/repository/org/springframework/spring-context/5.3.13/spring-context-5.3.13.jar:/home/starsray/.m2/repository/org/springframework/spring-expression/5.3.13/spring-expression-5.3.13.jar:/home/starsray/IdeaProjects/custom-starter/demo-spring-boot-starter/target/classes com.starsray.demoweb.DemoWebApplication
_ _ _
__ _ _ ___ | |_ ___ _ __ o O O ___ | |_ __ _ _ _ | |_ ___ _ _
/ _| | +| | (_-< | _| / _ \ | ' \ o (_-< | _| / _` | | '_| | _| / -_) | '_|
\__|_ \_,_| /__/_ _\__| \___/ |_|_|_| TS__[O] /__/_ _\__| \__,_| _|_|_ _\__| \___| _|_|_
_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""| {======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|
"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'./o--000'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'
2021-11-20 13:56:48.964 INFO 31707 --- [ main] com.starsray.demoweb.DemoWebApplication : Starting DemoWebApplication using Java 1.8.0_301 on starsray with PID 31707 (/home/starsray/IdeaProjects/custom-starter/demo-web/target/classes started by starsray in /home/starsray/IdeaProjects/custom-starter)
2021-11-20 13:56:48.966 INFO 31707 --- [ main] com.starsray.demoweb.DemoWebApplication : No active profile set, falling back to default profiles: default
2021-11-20 13:56:49.580 INFO 31707 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-11-20 13:56:49.587 INFO 31707 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-11-20 13:56:49.588 INFO 31707 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.55]
2021-11-20 13:56:49.627 INFO 31707 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-11-20 13:56:49.627 INFO 31707 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 625 ms
demo starter ---> demo config
2021-11-20 13:56:49.835 INFO 31707 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2021-11-20 13:56:49.842 INFO 31707 --- [ main] com.starsray.demoweb.DemoWebApplication : Started DemoWebApplication in 1.211 seconds (JVM running for 1.645)
可以看到测试输出内容,包括自定义banner也生效了。
demo starter ---> demo config
自定义配置信息提示
在使用Spring Boot官方提供的starter时候发现,每一个配置项都有提示信息,使用起来很方便,但是自定义的starter却没有提示,其实这里可以引入一个依赖来处理提示问题。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
spring提供了spring-boot-configuration-processor来加载配置信息,引入依赖后重新build一下项目,会发现在META-INF中出现spring-configuration-metadata.json文件,这就是存储的项目配置的元数据信息,再次写自定义配置项就会有提示了。
Spring Boot默认的场景启动器信息都存放在spring-boot-autoconfigure-2.6.0.jar中如下位置。
加载配置信息的依赖仅在开发阶段有用,在打包部署的时候,可以在打包插件中剔除这个依赖,减小应用包的体积。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
项目完整源码:https://gitee.com/starsray/test/tree/master/custom-starter
本文来自博客园,作者:星光Starsray,转载请注明原文链接:https://www.cnblogs.com/starsray/p/15564547.html