Spring 官方定义的 starter 通常命名遵循的格式为 spring-boot-starter-{name},例如 spring-boot-starter-web。非官方 starter 命名应遵循 {name}-spring-boot-starter 的格式,例如,dubbo-spring-boot-starter 。
创建一个Spring Boot项目,名称jsonformat-spring-boot-starter。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-autoconfigureartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.70version>
dependency>
<dependency>
<groupId>com.google.code.gsongroupId>
<artifactId>gsonartifactId>
<version>2.8.6version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.11.0version>
dependency>
接口
public interface FormatProcessor {
/**
* 定义一个格式化的方法
* @param obj
* @param
* @return
*/
<T> String format(T obj);
}
3个实现类
public class JacksonFormatProcessor implements FormatProcessor{
Logger logger=Logger.getLogger("JacksonFormatProcessor");
@Override
public <T> String format(T obj) {
ObjectMapper mapper = new ObjectMapper();
try {
logger.info("===========jackson format===========");
return mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
}
public class GsonFormatProcessor implements FormatProcessor{
Logger logger=Logger.getLogger("GsonFormatProcessor");
@Override
public <T> String format(T obj) {
Gson gson= new Gson();
logger.info("===========gson format===========");
return gson.toJson(obj);
}
}
public class FastjsonFormatProcessor implements FormatProcessor{
Logger logger=Logger.getLogger("FastjsonFormatProcessor");
@Override
public <T> String format(T obj) {
logger.info("===========fast-json format===========");
return JSON.toJSONString(obj);
}
}
/**
* 本配置类其实与spring-boot-starter的实现没啥关系,主要是为了解释Conditionals
* 深入了解:https://www.marcobehler.com/guides/spring-boot#_spring_boot_basics_conditionals
*/
@Configuration
public class FormatAutoConfiguration {
/**
* 下边3个Conditional注解代表三种满足条件下 bean注入
* 关于springboot,Conditional是springboot中每个组件的基础,判断是否使用该组件
*/
@Bean
@ConditionalOnProperty(prefix = "json.format", name = "enabled", havingValue = "true") //使用属性判断是否注入bean
public FormatProcessor fastjsonFormatProcessor(){
return new FastjsonFormatProcessor();
}
@Primary //默认开启jackson
@Bean
@ConditionalOnClass(name="com.google.gson.Gson") //在classpath下存在com.google.gson.Gson则注入bean
public FormatProcessor gsonFormatProcessor(){
return new GsonFormatProcessor();
}
@Bean
@Conditional(JacksonCondition.class) //使用condition判断是否注入bean
public FormatProcessor jacksonFormatProcessor(){
return new JacksonFormatProcessor();
}
}
  看名字 Template 大家也能知道,比如我们常用的 RedisTemplate、JdbcTemplate,构造函数的时候直接传入具体的实现。
public class FormatTemplate {
private FormatProcessor formatProcessor;
public FormatTemplate(FormatProcessor formatProcessor) {
this.formatProcessor = formatProcessor;
}
public <T> String doFormat(T obj){
return formatProcessor.format(obj);
}
}
@Import 用来导入配置类,就是将该配置类中的 Bean 注入到容器,@EnableConfigurationProperties 这是在将属性类激活,注入到spring容器中,也可以用 @Bean 的方式,@Configuration 说明这是一个配置类。接下来将 FormatTemplate 注入到容器中,我们看到首先是去属性类中去读属性,如果是 fastjson 就返回 fastjson 的实现,如果是 gson 就返回 gson 的实现,如果没读取到,就用前面设置的 @Primary 的默认实现。
@Import(FormatAutoConfiguration.class)
@EnableConfigurationProperties(FormatProperties.class)
@Configuration
public class JsonFormatConfiguration {
@Bean
public FormatTemplate formatTemplate(FormatProperties formatProperties,FormatProcessor formatProcessor){
if ("fastjson".equals(formatProperties.getType())){
return new FormatTemplate(new FastjsonFormatProcessor());
}else if ("gson".equalsIgnoreCase(formatProperties.getType())){
return new FormatTemplate(new GsonFormatProcessor());
}else if ("jackson".equalsIgnoreCase(formatProperties.getType())){
return new FormatTemplate(new JacksonFormatProcessor());
}
return new FormatTemplate(formatProcessor);
}
}
最后一步最关键的就是设置,在 resources 文件夹下创建 META-INF/spring.factories 文件,通过上面的知识,Spring Boot 在启动的时候就是读取该文件下的配置类,从而将 Bean 加载到容器中。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.github.autoconfigure.JsonFormatConfiguration
将jsonformat-spring-boot-starter项目通过mvn clean install
打包到本地maven仓库
新建一个spring-boot项目,测试自定义starter,引入pom
<dependency>
<groupId>com.githubgroupId>
<artifactId>jsonformat-spring-boot-starterartifactId>
<version>0.0.1-SNAPSHOTversion>
dependency>
properties配置,可以多切换几次,如gson、fastjson
json.format.type=jackson
测试类
@SpringBootApplication
public class SpringBootWebDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootWebDemoApplication.class, args);
}
}
@RestController
class TestController{
private FormatTemplate formatTemplate;
TestController(FormatTemplate formatTemplate) {
this.formatTemplate = formatTemplate;
}
@GetMapping("/test")
public String formatTest(){
return formatTemplate.doFormat(User.builder().id("1").name("ll").build());
}
}
@Data
@Builder
class User{
private String id;
private String name;
}
在浏览器访问localhost:8080/test,返回
// 20200602223544
// http://localhost:8080/test
{
"id": "1",
"name": "ll"
}
同时web日志中有打印你使用的json format 包
JacksonFormatProcessor : ===========jackson format===========
如果你需要代码请点击
参考
https://www.marcobehler.com/guides/spring-boot#_spring_boot_basics_conditionals
https://zhuanlan.zhihu.com/p/144241356