从零开始写一个SpringBoot Starter

11 篇文章 0 订阅
5 篇文章 0 订阅

一、什么是Starter

Starter是Spring Boot 中的一个非常重要的概念,Starter相当于模块,它能将模块所需的依赖整合起来并对模块内的Bean根据环境进行自动装配。使用者只需要依赖响应功能的Starter,无需做过多的配置和依赖,SpringBoot就能自动扫描并加载响应的模块。
例如:spring-boot-starter-web 就能使得项目支出Spring MVC,并且SpringBoot还为我们做了很多默认配置,无需再依赖spring-web、spring-webmvc等相关包。
SpringBoot存在很多开箱即用的Starter依赖,使得我们在开发业务代码时能够非常方便的,不需要过多关注框架的配置,而只需要关注业务

二、Starter编写

其实Starter本质与普通的Maven工程没有太大的区别。
本demo主要是简单梳理一下思路,选择的内容也比较简单根据需要选择注入来达到内容格式化的效果。所需要的依赖:

<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.58</version>
      <optional>true</optional>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>2.1.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-configuration-processor</artifactId>
      <version>2.2.5.RELEASE</version>
      <optional>true</optional>
    </dependency>
1.定义一个格式化接口
public interface FormatProcessor {
    //定义一个格式化的方法
    <T> String format(T obj);
}

JSON格式化:

public class JsonFormat implements FormatProcessor{
    @Override
    public <T> String format(T obj) {
        return "JsonFormatProcessor:"+ JSON.toJSONString(obj);
    }
}

字符串格式化:

public class StringFormat implements FormatProcessor{
    @Override
    public <T> 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<String,Object> info;

    public Map<String, Object> getInfo() {
        return info;
    }
    public void setInfo(Map<String, Object> 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 <T> String doFormat(T obj){
        StringBuilder builder = new StringBuilder();
        builder.append("begin : Execute format"). append("<br/>");
        builder.append("HelloProperties:").append(formatProcessor.format(helloProperties.getInfo())).append("<br/>");
        builder.append("Obj format result :").append(formatProcessor.format(obj)).append("\n");
        return builder.toString();
    }
}

对于这个方法应该都不会陌生,类似于常用到的redisTemplate和restTemplate。

到这里一个简单的Starter就完成了。下面进行打包,并复制pom中项目地址
在这里插入图片描述

三、测试

在另外新建一个SpringBoot项目 引入上面依赖。

	<dependency>
            <groupId>com.ccc.starter</groupId>
            <artifactId>format-spring-boot-starter</artifactId>
            <version>1.0-SNAPSHOT</version>
   </dependency>

在配置文件中输入: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中导入依赖

 		<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.58</version>
        </dependency>

在测试
在这里插入图片描述
StringFormat就变成了JsonFormat。原因是我们在Starter中使用**@ConditionalOnMissingClass@ConditionalOnClass**进行选择注入。这两个注解简单来说就是一个if-else的关系。

到此,一个简单的Starter就完成了,如果您发现有啥错误的地方,恳请指出批评。在此感谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈橙橙丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值