我们在项目中经常会引用一些spring-boot-starter-xxx之类的依赖,然后就在配置文件中进行配置 ,例如:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://10.82.232.149:3306/rc?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&zeroDateTimeBehavior=round&serverTimezone=UTC&allowMultiQueries=true
username: root
password: sf.qz
hikari:
pool-name: Hikari-Pool
idle-timeout: 30000
maximum-pool-size: 50
minimum-idle: 10
servlet:
multipart:
max-file-size: -1
max-request-size: -1
http:
multipart:
maxRequestSize: -1
maxFileSize: -1
那么我们能否自定义个starter工程呢? 答案是:yes
一、创建自定义的 jsonformatter-spring-boot-starter工程
通常一些第三方的starter依赖都是按照xxx-spring-boot-starter 的格式去命名的,所以我们按照这种方式创建一个jsonformatter-spring-boot-starter 工程,该工程主要就是利用fastjson 和 gson 进行对象和json字符串之间的互相转换。
<?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.dzx.springboot</groupId>
<artifactId>jsonformatter-spring-boot-starter</artifactId>
<version>1.0.0</version>
<name>jsonformatter-spring-boot-starter</name>
<description>json转换starter</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
二、编写json转换业务相关类
package com.dzx.springboot.jsonformatterspringbootstarter.config;
/**
* @author 80004819
* @ClassName:
* @Description:
* @date 2020年09月27日 11:17:07
*/
public interface FormatProcessor {
//定义一个格式化的方法
String objectToJson(Object obj);
Object jsonToObject(String str,Class aClass);
}
package com.dzx.springboot.jsonformatterspringbootstarter.config;
import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import org.springframework.stereotype.Component;
import sun.swing.plaf.synth.SynthIcon;
/**
* @author 80004819
* @ClassName:
* @Description:
* @date 2020年09月27日 10:30:38
*/
@Component("jsonFormatterTemplate")
public class JsonFormatterTemplate implements FormatProcessor{
/**
* 格式化器
*/
private Object formatter;
public Object getFormatter() {
return formatter;
}
public void setFormatter(Object formatter) {
this.formatter = formatter;
}
/**
* 将对象转成字符串
*
* @param o
* @return
*/
public String objectToJson(Object o) {
if (this.formatter instanceof JSON) {
System.out.println("使用fastjson转换数据");
return JSON.toJSONString(o);
}
System.out.println("使用gson转换数据");
return new Gson().toJson(o);
}
/**
* 将字符串转成对象
* @param str
* @return
*/
public Object jsonToObject(String str, Class aClass) {
if (this.formatter instanceof JSON) {
System.out.println("使用fastjson转换数据");
return JSON.parse(str);
}
System.out.println("使用gson转换数据");
return new Gson().fromJson(str, aClass);
}
}
三、编写property类,用来读取配置文件中的配置项
package com.dzx.springboot.jsonformatterspringbootstarter.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
/**
* @author 80004819
* @ClassName:
* @Description:
* @date 2020年09月27日 10:23:08
*/
@ConfigurationProperties(prefix = "json.formatter")
@Configuration
public class JsonFormatterProperty {
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
四、编写Configuration 和 autoConfiguration类
package com.dzx.springboot.jsonformatterspringbootstarter.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.JdbcProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
/**
* @author 80004819
* @ClassName:
* @Description:
* @date 2020年09月27日 10:34:39
*/
@Configuration
//启用对添加了@ConfigurationProperties注解类的支持,使之能够以bean的形式进行注入
@EnableConfigurationProperties({JsonFormatterProperty.class})
public class JsonFormatterConfiguration {
@Bean("jsonFormatterTemplate")
@Primary
public JsonFormatterTemplate jsonFormatterTemplate(JsonFormatterProperty jsonFormatterProperty) throws Exception {
JsonFormatterTemplate jsonFormatterTemplate = new JsonFormatterTemplate();
Object o = Class.forName(jsonFormatterProperty.getType()).newInstance();
jsonFormatterTemplate.setFormatter(o);
return jsonFormatterTemplate;
}
}
package com.dzx.springboot.jsonformatterspringbootstarter.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
/**
* @author 80004819
* @ClassName:
* @Description:
* @date 2020年09月27日 10:33:15
*/
@Configuration
@ConditionalOnClass({JsonFormatterTemplate.class})
//以组件的形式导入JsonFormatterConfiguration
@Import({JsonFormatterConfiguration.class})
//如果application.properties中json.formatter.enabled=true 则启用自动配置
@ConditionalOnProperty(prefix = "json.formatter", value = "enabled", matchIfMissing = true)
public class JsonFormatterAutoConfiguration {
}
五、配置spring.factories文件
做完以上步骤之后,我们的自动化配置类就算是完成了,接下来还需要一个 spring.factories 文件,那么这个文件是干嘛的呢?大家知道我们的 Spring Boot 项目的启动类都有一个 @SpringBootApplication 注解,这个注解的定义如下:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM,
classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}
大家看到这是一个组合注解,其中的一个组合项就是 @EnableAutoConfiguration ,这个注解是干嘛的呢?
@EnableAutoConfiguration 表示启用 Spring 应用程序上下文的自动配置,该注解会自动导入一个名为 AutoConfigurationImportSelector 的类,而这个类会去读取一个名为 spring.factories 的文件, spring.factories 中则定义需要加载的自动化配置类,我们打开任意一个框架的 Starter ,都能看到它有一个 spring.factories 文件,例如 MyBatis 的 Starter 如下:
那么我们自定义 Starter 当然也需要这样一个文件,我们首先在 Maven 项目的 resources 目录下创建一个名为 META-INF 的文件夹,然后在文件夹中创建一个名为 spring.factories 的文件,文件内容如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.dzx.springboot.jsonformatterspringbootstarter.config.JsonFormatterAutoConfiguration
在这里指定我们的自动化配置类的路径即可。
如此之后我们的自动化配置类就算完成了。
六、本地安装
如果在公司里,大伙可能需要将刚刚写好的自动化配置类打包,然后上传到 Maven 私服上,供其他同事下载使用,我这里就简单一些,我就不上传私服了,我将这个自动化配置类安装到本地仓库,然后在其他项目中使用即可。安装方式很简单,在 IntelliJ IDEA 中,点击右边的 Maven Project ,然后选择 Lifecycle 中的 install ,双击即可,如下:
双击完成后,这个 Starter 就安装到我们本地仓库了,当然小伙伴也可以使用 Maven 命令去安装。
七、使用 Starter
接下来,我们来新建一个普通的 Spring Boot 工程,这个 Spring Boot 创建成功之后,加入我们自定义 Starter 的依赖,如下:
<dependency>
<groupId>com.dzx.springboot</groupId>
<artifactId>jsonformatter-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
此时我们引入了上面自定义的 Starter ,也即我们项目中现在有一个默认的 jsonFormatterTemplate 实例可以使用,而且关于这个实例的数据,我们还可以在 application.properties 中进行配置,如下:
json:
formatter:
enabled: true
type: com.alibaba.fastjson.JSONObject
配置完成后,我们可以编写一个测试controller
package com.sf.gis.boot.rcboot.controller;
import com.dzx.springboot.jsonformatterspringbootstarter.config.JsonFormatterTemplate;
import com.sf.gis.boot.rcboot.shiro.entity.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 80004819
* @ClassName:
* @Description:
* @date 2020年09月27日 11:13:43
*/
@RestController
@RequestMapping("/json")
public class JsonController {
@Autowired
private JsonFormatterTemplate jsonFormatterTemplate;
@GetMapping("/trans")
public void trans() {
String dzx = jsonFormatterTemplate.objectToJson(new SysUser().setName("dzx"));
System.out.println(dzx);
Object o = jsonFormatterTemplate.jsonToObject(dzx,SysUser.class);
System.out.println(((SysUser) o).getName());
}
}
使用 postman或者swagger请求 http://localhost:8085/json/trans,看到控制台打印如下:
如果我们需要使用gson呢,可以直接修改配置文件如下:
json:
formatter:
enabled: true
type: com.google.gson.Gson
再次请求 http://localhost:8085/json/trans,看到控制台打印如下:
至此结束~~