1、如何自定义starter
官方指定的starter的命名格式是spring-boot-starter-xxx ,而我们自己自定义的命名建议是xxx-spring-boot-starter , 比如mybatis-spring-boot-starter
自定义的starter和官方的starter都是在spring boot应用启动的时候去扫描classpath下面的META-INF下的spring.factories文件,查看里面的xxxAutoConfiguration,如果有就装配进spring的ioc容器中,并进行自动配置。
自定义starter的步骤如下:
- 创建一个空项目(如果已有项目就不用创建了)
- 创建一个自定义的自动配置模块(spring boot项目)
- 创建一个自定义的启动器模块(可以是springboot或者maven项目,只是用来导入自动配置类依赖的)
- 测试
2、创建自定义starter项目
- 创建一个空项目命名为:diy-spring-boot-starter
- 创建自动配置类模块
一直下一步,创建完项目就可以了!
删除无用文件
删除主启动类,配置文件,测试类,因为我们用不到
删除测试依赖和打包插件,我们也用不到
- 创建启动器模块(我这里创建的是maven)
导入自动配置类依赖
<dependencies>
<dependency>
<groupId>cn.butcher</groupId>
<artifactId>student-spring-boot-autoconfiguration</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
- 项目结构
很干净的项目
3、编写自动配置
- 主要的步骤是,创建一个Student类作为测试
- 创建StudentAutoConfiguration自动配置类
- 创建StudentProperties配置类
注意是在我们的student-spring-boot-autoconfiguration中编写
3.1 创建学生类
package cn.butcher;
public class Student {
private String name;
private String major;
public Student(String name, String major) {
this.name = name;
this.major = major;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", major='" + major + '\'' +
'}';
}
}
这里有一个是需要注意的,我们需要写上set和get方法,因为spring它的注入就是使用的DI注入,所以set get方法不可少 (当然,我们表达可能有误,可能不只是DI注入)
3.2 创建自动配置类StudentAutoConfiguration
自动配置类中有一个方法返回一个学生
package cn.butcher;
import org.springframework.context.annotation.Configuration;
@Configuration
public class StudentAutoConfiguration {
public Student getStudent(){
return new Student("谭熙","信管");
}
}
到这里,我们发现,student中的属性,应该是从我们的配置文件中获取到的,所以在这里我们不能写死。
我们需要创建一个配置类
3.3 创建配置类StudentProperties
需要使用@ConfigurationProperties(prefix = “butcher”)注解表示这是spring的配置文件,在自动装配的时候,才会读取 prefix = "butcher"指定配置的前缀为butcher
package cn.butcher;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "butcher")
public class StudentProperties {
// 给他一个默认值,我们就不必去配置了!
// 如果我们的需求变了,那就在配置文件中写配置就可以了!
// 这也是spring boot零配置我们就能启动一个应用的根本所在
private Student student = new Student("谭熙","信管");
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}
注意,这时候你的idea可能会提示爆红,不要管它,这是因为这个配置类没有引用到
3.4 在StudentAutoConfiguration 中引入配置类
使用@EnableConfigurationProperties(StudentProperties.class)注解使我们的配置类生效
package cn.butcher;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(StudentProperties.class)
public class StudentAutoConfiguration {
// 将学生类注入到spring ioc容器中 注意这个方法里面的studentProperties因为
// 我们在上面@EnableConfigurationProperties注解中绑定了,所以会进行自动注入
// 当然,也可以写@Autowired
@Bean
public Student getStudent(StudentProperties studentProperties){
return studentProperties.getStudent();
}
}
3.5 在classpath下创建spring.factories文件
注意我们需要先创建META-INF目录
如果你的颜色没有变,就请检查以下自己的是不是写错了
在里面注册我们的自动配置类,因为springboot在启动的时候会扫描这个文件,去找到我们的自动配置类进行自动配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.butcher.StudentAutoConfiguration
注意这里的 \ 只是换行效果,你也可以把配置文件写在一行
至此,我们的自定义starter就编写完毕了,我们进行测试
4、测试
在pom.xml文件中导入我们启动器依赖
<dependency>
<groupId>cn.butcher</groupId>
<artifactId>student-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
进入测试类测试以下!
package cn.butcher;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class TestDiyStarterApplicationTests {
@Autowired
Student student;
@Test
void contextLoads() {
System.out.println(student);
}
}
结果确为我们所期待的,这是默认配置是我们在编写配置类的时候默认写上的
那现在我们需要改配置了,我们就需要到application.yaml文件中去做修改
butcher:
student:
name: 张三
major: 电商
完美了!
最后有一个小问题不知道你们会不会遇到,如果是在application.properties里面去写中文,虽然也能生效,但是却乱码了,换成yaml的就不会。
使用yaml就好,这是官方推荐的,并且确实比properties好用。