-
Notifications
You must be signed in to change notification settings - Fork 0
Description
实现一个简单的SpringBoot-Starter
我们使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中。Starter 为我们带来了众多的自动化配置,有了这些自动化配置,我们可以不费吹灰之力就能搭建一个生产级开发环境,有的小伙伴会觉得这个 Starter 好神奇呀!其实 Starter 也都是 Spring 中的基础知识点实现的,今天codeman就来带大家自己来实现一个 Starter ,慢慢揭开 Starter 的神秘面纱!
核心知识
一个starter一般包含下面的内容:
-
一个被@ConfigurationProperties注解的配置类
这个类用来动态的读取用户的配置信息
-
一个开启自动配置的类
SpringBoot将会通过这个配置类开启自动配置。
具体的方法后面再说。然后我们一般都会给自动配置类添加一个@conditional注解,这样在符合某些条件时,开启自动配置,在某些情况下不开启自动配置。 -
一个完成特定功能的类
我们的starter最终还是要提供某些服务的。所以我们还要编写真正的提供服务的类,通常这个类会被注册为一个bean。
然后,如果你对我之前提到的几个注解不属性,可以看这里
https://github.com/codeman-cs/SpringBoot/wiki/An-overview-of-25-Spring-Boot-core-annotations
阅读下面的文章之前,你需要掌握这几个注解的用法。
实践
所谓的 Starter ,其实就是一个普通的 Maven 项目,因此我们自定义 Starter ,需要首先创建一个普通的 Maven 项目,创建完成后,添加 Starter 的自动化配置类即可,如下:
创建一个普通maven项目,添加下面的依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>这就是我们项目的基本骨架。
创建我们的配置类
package com.github.codeman.mystarter;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "codeman")
public class CodemanProperties {
private static final String DEFAULT_NAME = "codeman";
private static final String DEFAULT_MSG = "learn program in a better way";
private String name = DEFAULT_NAME;
private String msg = DEFAULT_MSG;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}这个配置类很简单,@ConfigurationProperties(prefix = "codeman")会自动读取application.properties里面的以codeman开头的配置属性。将来我们在applicaton.properties中配置的codeman.name、codeman.msg就会被读取进来并赋值给相应的属性。
创建我们的功能类
一个starter总是要完成特定的事情的,这里我就写一个最简单的服务类,实际的项目中这个可能非常复杂。
public class CodemanService {
private String msg;
private String name;
public String sayHello() {
return name + " say " + msg + " !";
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}这个服务类也没有做什么特别的事情,等会我们在自动配置时,把它注册为一个bean就行了。
自动配置类
这里就是重点了,我们的自动配置类是这样的。
@Configuration
@EnableConfigurationProperties(CodemanProperties.class)
@ConditionalOnClass(CodemanService.class)
public class CodemanServiceAutoConfiguration {
@Autowired
CodemanProperties codemanProperties;
@Bean
CodemanService codemanService() {
CodemanService codemanService = new CodemanService();
codemanService.setMsg(codemanProperties.getMsg());
codemanService.setName(codemanProperties.getName());
return codemanService;
}
}-
@Configuration表明这是一个配置类 -
@EnableConfigurationProperties(CodemanProperties.class)因为我之前在
CodemanProperties这个类中使用了ConfigurationProperties,所以我们这里要有一个配套的@EnableConfigurationProperties。 -
具体实现
然后我们在配置类中将我们的CodemanService注册成了一个Bean,这样其他模块在使用我们这个模块是时候,就可以直接使用我们的CodemanService了。
不过你可能注意到了,我还写了这个注解
@ConditionalOnClass(CodemanService.class)
它的语义就是存在CodemanService.class这个类的时候,开启自动配置,否则这个类不发生作用。
当然你也可以添加下面这些注解:
-
@ConditionalOnProperty
Combine @conditional annotations to enable configuration when the specified property has a specified value.
-
@ConditionalOnExpression
Combine @conditional annotations to enable configuration when the SpEL expression is true.
当然,你可以不写任何的@conditional注解,如果这样的话,你的配置类总是会开启的。
注册配置类
最后一步,为了能让我们的自动配置类发挥作用,我们需要把它按照特定的方式注册。
SpringBoot约定:springboot会先检查META-INF这个文件夹里面的spring.factories文件,并读取下面这个字段。总之按照下面这样写就行了。
实践
编写完我们的配置类后,我们测试一下。
- 安装到本地
直接在当前项目的根目录下执行这个命令,就可以将当前的模块打包成jar文件并安装到本地了
$ mvn install- 创建一个新的项目,用来测试
然后创建一个新的SpringBoot项目,然后添加这个依赖。
<dependency>
<groupId>com.github.codeman</groupId>
<artifactId>mystarter</artifactId>
<version>0.0.1</version>
</dependency>- 编写一个简单的服务。
- 再添加一些配置信息。
- 最后启动下我们的服务器
可以看到,我们的starter确实起到的作用,codemanService被自动注册到我们的项目中。
总结
然后对于如果你想编写自己的starter,你就应给修改:
-
CodemanService
这是将是你真正工作的类。
-
CodemanProerties
你将通过这个配置类读取用户的配置信息。
-
@Conditanal
取决于你希望在什么情况下开启自动配置。





