我们通过手写一个starter,实现一个这样的功能:如果存在FastJson包则将对象以json形式输出,否则以对象的toString()输出。另外引入这个starter后我们不希望有任何的配置(自动配置),开箱即用。此文并不探究starter的原理,只希望读者可以初步了解一个starter的开发流程。
步骤1:新建一个空maven工程,并在pom.xml中导入如下依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
步骤2:通过maven项目,编写一个starter
2.1编写接口
public interface FormatProcessor {
<T> String format(T obj);
}
2.2编写两个实现类
public class JsonFormatProcessor implements FormatProcessor {
public <T> String format(T obj) {
return "JsonFormatProcess"+ JSON.toJSONString(obj);
}
}
public class StringFormatProcessor implements FormatProcessor {
public <T> String format(T obj) {
return "StringFormatProcessor:"+ Objects.toString(obj);
}
}
2.3编写一个自动注入bean的类
@Import(FormatAutoConfiguration.class)
@Configuration
public class HelloAutoConfiguration {
public HelloFormatTemplate helloFormatTemplate(FormatProcessor formatProcessor){
return new HelloFormatTemplate(formatProcessor);
};
}
@Configuration
public class FormatAutoConfiguration {
@ConditionalOnMissingClass("com.alibaba.fastjson.JSON")
@Bean
@Primary
public FormatProcessor StringFormat(){
return new StringFormatProcessor();
}
@ConditionalOnClass(name = "com.alibaba.fastjson.JSON")
@Bean
public FormatProcessor jsonFormat(){
return new JsonFormatProcessor();
}
}
2.4,对外提供一个template
public class HelloFormatTemplate {
private FormatProcessor formatProcessor;
public HelloFormatTemplate(FormatProcessor formatProcessor) {
this.formatProcessor = formatProcessor;
}
public <T> String doFormat(T obj){
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Execute format:").append("\n");
stringBuilder.append("Obj format result:").append(formatProcessor.format(obj)).append("\n");
return stringBuilder.toString();
}
}
2.5配置spring.factories
如果读者对JDK的SPI机制熟悉的话,对下面的配置应该感到很熟悉。接下来我们需要在resources目录下创建META-INF文件夹,并在这个文件夹中新建一个名叫spring.factories的文件
spring.factories中我们指定需要自动配置的配置类DemoAutoConfig,Spring在启动时会自动加载这个配置文件,找到我们的配置类,注意配置的是全类名。细心的同学可能会问,FormaterConfig也需要自动配置呀,怎么这里怎么只需要配置DemoAutoConfig呢,因为我们在DemoAutoConfig中用到了@Import注解将它导入进来啦。
改starter编写完成,运行命令mvn clean install将我们的工程发布到本地仓库。
下面我们新建一个SpringBoot工程的项目导入我们写好的这个starter。
3.1Template需要序列化输出一个类,现在我们就来定义一个类,并重写它的toString方法
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
3.2引入maven项目以来,即可运行;
@Autowired
HelloFormatTemplate helloFormatTemplate;
@GetMapping("/format")
public String format(){
User user = new User();
user.setAge(18);
user.setName("MIC");
return helloFormatTemplate.doFormat(user);
}
3.3,如果我们再该springboot项目中,未引入fastjson依赖,则就以对象toString形式输出。
如果项目中引入了JSON依赖,则就以对象json形式输出