Starter是Spring Boot 中的一个非常重要的概念,Starter相当于模块,它能将模块所需的依赖整合起来并对模块内的Bean根据环境进行自动装配。使用者只需要依赖响应功能的Starter,无需做过多的配置和依赖,SpringBoot就能自动扫描并加载响应的模块。 例如:spring-boot-starter-web 就能使得项目支出Spring MVC,并且SpringBoot还为我们做了很多默认配置,无需再依赖spring-web、spring-webmvc等相关包。 SpringBoot存在很多开箱即用的Starter依赖,使得我们在开发业务代码时能够非常方便的,不需要过多关注框架的配置,而只需要关注业务
二、Starter编写其实Starter本质与普通的Maven工程没有太大的区别。 本demo主要是简单梳理一下思路,选择的内容也比较简单根据需要选择注入来达到内容格式化的效果。所需要的依赖:
junit
junit
4.11
test
com.alibaba
fastjson
1.2.58
true
org.springframework.boot
spring-boot-starter
2.1.5.RELEASE
org.springframework.boot
spring-boot-configuration-processor
2.2.5.RELEASE
true
1.定义一个格式化接口
public interface FormatProcessor {
//定义一个格式化的方法
String format(T obj);
}
JSON格式化:
public class JsonFormat implements FormatProcessor{
@Override
public String format(T obj) {
return "JsonFormatProcessor:"+ JSON.toJSONString(obj);
}
}
字符串格式化:
public class StringFormat implements FormatProcessor{
@Override
public String format(T obj) {
return "StringFormatProcessor:"+ Objects.toString(obj);
}
}
进行注入:
@Configuration
public class FormatAutoConfiguration {
@ConditionalOnMissingClass(value = "com.alibaba.fastjson.JSON") //如果没有这个类的时候 注入
@Bean
@Primary //优先级较高的装载
public FormatProcessor stringFormat(){
return new StringFormat();
}
@ConditionalOnClass(name = "com.alibaba.fastjson.JSON") //有的话注入这个
@Bean
public FormatProcessor jsonFormat(){
return new JsonFormat();
}
}
配置文件的编写:
@ConfigurationProperties(prefix = HelloProperties.HELLO_FORMAT_PREFIX)
public class HelloProperties {
//配置前缀
public static final String HELLO_FORMAT_PREFIX = "com.ccc.format";
//存储配置信息
private Map info;
public Map getInfo() {
return info;
}
public void setInfo(Map info) {
this.info = info;
}
}
编写Properties配置文件并且指定配置前缀,那么这个有什么用呢? 我们SpringBoot项目中,通常会有一个applicaiton.properties/yml文件来进行配置。举个最简单的例子你输入一个server他会出现server.port配置,你输入spring.datasource会出现很多关于数据库的配置。那么这些功能就是由此代码来实现的。待会会举例。
注入配置文件:
@Configuration
@EnableConfigurationProperties(HelloProperties.class)
@Import(FormatAutoConfiguration.class)
public class HelloAutoConfiguration {
@Bean
public HelloFormatTemplate helloFormatTemplate(FormatProcessor formatProcessor,HelloProperties properties){
return new HelloFormatTemplate(formatProcessor,properties);
}
}
编写一个模板方法:
public class HelloFormatTemplate {
private FormatProcessor formatProcessor;
private HelloProperties helloProperties;
public HelloFormatTemplate(FormatProcessor formatProcessor,HelloProperties helloProperties) {
this.formatProcessor = formatProcessor;
this.helloProperties = helloProperties;
}
/**
* 简单写一段输出语句来区分两种格式化
*/
public String doFormat(T obj){
StringBuilder builder = new StringBuilder();
builder.append("begin : Execute format"). append("");
builder.append("HelloProperties:").append(formatProcessor.format(helloProperties.getInfo())).append("");
builder.append("Obj format result :").append(formatProcessor.format(obj)).append("\n");
return builder.toString();
}
}
对于这个方法应该都不会陌生,类似于常用到的redisTemplate和restTemplate。
到这里一个简单的Starter就完成了。下面进行打包,并复制pom中项目地址
在另外新建一个SpringBoot项目 引入上面依赖。
com.ccc.starter
format-spring-boot-starter
1.0-SNAPSHOT
在配置文件中输入:com.ccc就会出现提示 简单写几个信息
@RestController
public class FormatController {
@Autowired
HelloFormatTemplate helloFormatTemplate;
@GetMapping("format")
public String format(){
//随便建个实体类
User user = new User();
user.setAge(18);
user.setName("张三");
return helloFormatTemplate.doFormat(user);
}
}
启动测试: 发现启动报错了,失败原因很简单,注入失败了。 原因是在我们引入依赖的时候SpringBoot并没有扫描到所以无法注入。如何解决呢? 在我们的Starter工程中的resouces下新建META-INF文件夹,并新建一个spring.factories文件并写入主动注入配置指向我们的配置类。关于这点我在另一篇文章中也大致提到了SpringBoot的自动装配原理,有兴趣的朋友可以看看:分析SpringBoot自动装配原理
org.springframework.boot.autoconfigure.EnableAutoConfiguration =\
com.ccc.starter.autoconfiguration.HelloAutoConfiguration
在进行打包测试。 启动成功。 你会发现在配置文件中信息也能获取到也就达到配置效果了。 那么这里为什么是StringFormat的格式化呢? 因为我们没有在SpringBoot的pom中导入依赖
com.alibaba
fastjson
1.2.58
在测试 StringFormat就变成了JsonFormat。原因是我们在Starter中使用**@ConditionalOnMissingClass和@ConditionalOnClass**进行选择注入。这两个注解简单来说就是一个if-else的关系。
到此,一个简单的Starter就完成了,如果您发现有啥错误的地方,恳请指出批评。在此感谢!