springboot中如果需要引入某个功能,只要引入它的starter包,就能自动加载它所有的依赖包和配置,非常方便。我们可以自己制作starter包,作为一个组件,给其他系统引用。
1、命名规则
官方starter包:spring-boot-starter-{模块名}
第三方starter包:{模块名}-spring-boot-starter
2、starter包用到了springboot自动装配功能
参考druid-spring-boot-starter-1.1.21.jar,建立一个starter的maven项目:sms-spring-boot-starter
3、制作starter包,有两种方式
方式一:像druid一样全部写在一起,编译出一个jar包
方式二:像pagehelper-spring-boot-starter一样,建立maven多模块项目
<modules>
<module>pagehelper-spring-boot-autoconfigure</module>
<module>pagehelper-spring-boot-starter</module>
<module>pagehelper-spring-boot-samples</module>
</modules>
这里作为演示,所以都写在一个模块里
4、建立pom.xml文件
<?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>
<groupId>com.example</groupId>
<artifactId>sms-spring-boot-starter</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>sms-spring-boot-starter</name>
<description>send sms</description>
<properties>
<spring-boot.version>2.1.8.RELEASE</spring-boot.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- 引入springframework依赖包版本 -->
<dependency>
<!-- Import dependency management from Spring Boot,not include plugin
management as the parent import style -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Compile dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!-- Optional dependencies -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- @ConfigurationProperties annotation processing (metadata for IDEs) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
说明:
spring-boot-autoconfigure:作用是实现自动装配功能
spring-boot-configuration-processor:作用是编译时生成spring-configuration-metadata.json,此文件是给IDE提示信息使用
5、在/src/main/java下建立包com.example.sms
创建MyMessage.java
package com.example.sms;
/**
* 模拟发送短信功能
* @author user
*
*/
public class MyMessage {
public void send(String phone, String msg) {
System.out.println("send to: " + phone + ", msg: " + msg);
}
}
创建SmsAutoConfiguration.java
package com.example.sms;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(SmsProperties.class)
public class SmsAutoConfiguration {
@Bean
public MyMessage myMessage() {
return new MyMessage();
}
}
创建SmsProperties.java
package com.example.sms;
import java.util.Properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "sms.properties")
public class SmsProperties {
private Properties properties = new Properties();
/**
* 超时时间
*/
private String timeout;
/**
* 重试次数
*/
private String retry;
public String getTimeout() {
return properties.getProperty("timeout");
}
public void setTimeout(String timeout) {
properties.setProperty("timeout", timeout);
}
public String getRetry() {
return properties.getProperty("retry");
}
public void setRetry(String retry) {
properties.setProperty("retry", retry);
}
}
实现作用:
SmsAutoConfiguration类创建MyMessage对象和SmsProperties对象
SmsProperties类加载配置文件中的配置项
6、注解说明
@ConfigurationProperties:自定义属性配置类
@EnableConfigurationProperties:使@ConfigurationProperties注解的类生效,并且将该类注入到IOC容器中,交由IOC容器进行管理
@ConditionalOnBean:spring容器中存在指定class的实例对象时,对应的配置才生效
@ConditionalOnClass:classpath中存在指定class时的实例对象时,对应的配置才生效
@Import:把类的实例加入spring的IOC容器中
@AutoConfigureBefore:在指定的Configuration类之前加载
@AutoConfigureAfter:在指定的Configuration类之后加载
7、在src/main/resources下建立文件夹META-INF,在META-INF下建立spring.factories
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.sms.SmsAutoConfiguration
8、引用sms-spring-boot-starter包
另一个项目pom文件,添加依赖:
<!-- 自定义starter包 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>sms-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
添加测试类StarterTest.java:
package myboot;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.example.myboot.MybootApplication;
import com.example.sms.MyMessage;
import com.example.sms.SmsProperties;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MybootApplication.class)
public class StarterTest {
@Autowired
MyMessage myMessage;
@Autowired
SmsProperties smsProperties;
@Test
public void testSend() {
System.out.println("timeout is: " + smsProperties.getTimeout());
System.out.println("retry is: " + smsProperties.getRetry());
myMessage.send("13600000001", "你好");
}
}
执行结果:
timeout is: 1000
retry is: 6
send to: 13600000001, msg: 你好
引入的starter包的目录结构:
加载流程
springboot启动 --> 通过spring.factories加载xxxAutoConfiguration类 --> 内部加载xxxProperties类获取配置文件中的属性,或者创建bean
参考资料:
https://cloud.tencent.com/developer/article/1415098
https://www.cnblogs.com/zhoading/p/12194960.html
http://www.hyhblog.cn/2018/08/29/spring-boot-unable-to-read-meta-data-for-class/