手写spring-boot-starter(一学就会系列)

什么是starter呢?

Spring Boot 对比 Spring MVC 最大的优点就是使用简单,约定大于配置。不会像之前用 Spring MVC 的时候,时不时被 xml 配置文件搞的晕头转向,冷不防还因为 xml 配置上的一点疏忽,导致整个项目莫名其妙的不可用,顿感生活无所依恋,简称生无可恋。

这要归功于组成了 Spring Boot 的各种各样的 starters,有官方提供的,也有第三方开源出来。可以这么说,基本上你打算用的功能都可以找到,如果没有找到,那就再找一找。

用 Spring Boot 的功能组件(例如 spring-boot-starter-actuator、 spring-boot-starter-data-redis 等)的步骤非常简单,用著名的把大象放冰箱的方法来概括的话,有以下三步就可以完成组件功能的使用:

Step1

在 pom 文件中引入对应的包,例如:

<dependency> 
  <groupId>org.springframework.boot</groupId>  
  <artifactId>spring-boot-starter-redis</artifactId> 
</dependency>

Step2

在peroperties或者yml中加入相应的配置,配置都是组件约定好的,需要查看官方文档或者相关说明。

Step3

以上两步都正常的情况下,我们就可以使用组件提供的相关接口来开发业务功能了。

没错吧,这个过程我们在日常的开发中不知道已经实践了多少遍。那么 Spring Boot 为什么能做到如此简单易用呢,它内部是什么样的工作机制呢,不知道你有没有研究过。

@Autowired
RedisTemplete redisTemplete;

开始之前,我们要理解一下 spring boot starter 是什么呢?

它把需要用的其他依赖都囊括进来,放在starter类里面的pom中,把各种依赖的关系都给确定了,打通各个组件之间的连接,并且在中间帮我们省去了很多配置,力图做到使用最简单。

实现一个 starter 有四个要素:

1.starter 命名 ;
2.自动配置类,用于自动创建bean,并交给spring容器 ;
3.自动配置类需要的配置文件 spring.factories ;
4.业务类(参考redisTemplete类) ;

1. 给 starter 起个名字

官方的 starter 的命名格式为:spring-boot-starter-xxx
非官方的 starter 的命名格式为:xxx-spring-boot-starter
你不按人家规范取也行,只是个规范。
我这里取名为plusroax

    <groupId>com.plusroax</groupId>
    <artifactId>plusroax-spring-boot-starter</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>

2. 引入自动配置包及其它相关依赖包

实现 starter 主要依赖自动配置注解,所以要在 pom 中引入自动配置相关的两个 jar 包**【必须引入】**

除此之外,根据你的业务引入你需要的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
</dependency>

3.配置类

此类是读取properties、yml中数据的。比如需要读取配置的ip和port属性,可以这么写:

@Data
@ConfigurationProperties("plusroax.address")
public class KiteProperties {
    private String host;
    private int port;
}

@ConfigurationProperties配置的是yml、properties中属性的前缀

4.业务类

此类是你的核心业务类,别人引入你的starter,是想用到你的方法,比如redisTemplete。

我这里就把从properties、yml中获取的数据打印出来。

public class MyTemplete {
    private String host;
    private int port;
    
    public MyTemplete (MyProperties myProperties){
        this.host = myProperties.getHost();
        this.port = myProperties.getPort();
    }

    public void print(){
        System.out.println(this.host + ":" +this.port);
    }
}

5.自动配置类

此类是关键,能否自动创建bean,就看这个类。

@Configuration 
@ConditionalOnClass(MyService.class) 
@EnableConfigurationProperties(MyProperties.class)
public class MyAutoConfigure {
    @Autowired
    private MyProperties myProperties;

    /**
     * 下面是要创建的bean,注意!只有满足注解上的条件,才会去自动创建bean
     */
    @Bean
    @ConditionalOnMissingBean(MyService.class) 
    @ConditionalOnProperty(prefix = "plusroax.address",value = "enabled", havingValue = "true",matchIfMissing = true)
    MyTemplete myTemplete (){
        return new MyTemplete (myProperties);
    }
}

@Configuration:表明这是一个配置类
@ConditionalOnClass(MyService.class:只有在当前类路径下存在MyService这个类的情况下,才会解析该该自动配置类(MyAutoConfigure),否则不解析。
@EnableConfigurationProperties(MyProperties.class) :用哪个类读取yml、properties中配置的参数

@ConditionalOnMissingBean(MyService.class) :当前上下文还没有 MyService的 bean 实例的情况下,才会执行 kiteService() 方法,从而实例化一个 bean 实例出来。反则不会执行,自然也不会创建
@ConditionalOnProperty(prefix = “plusroax.address”,value = “enabled”, havingValue = “true”,matchIfMissing = true) :绑定指定前缀去读取,matchIfMissing默认为false,只有去配置plusroax.address.enabled=true才会创建bean。改成ture,无论如何都会创建bean

6.创建 spring.factories 文件

在 resource/META-INF 目录下创建名称为 spring.factories 的文件,当 Spring Boot 启动的时候,会在 classpath 下寻找所有名称为 spring.factories 的文件。在这里指定的自动配置类,多个值使用逗号隔开。

例如本例中的配置信息是这样的:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.plusroax.autoconfig.MyAutoConfigure

=号前面的是固定的;后面是配置你的全路径类名
这里的 反斜杠 是换行的意思,不想换行就直接把全路径类名写在等号后面。

7.打包项目(install)

打包完之后,就大功告成了,你已经会手写starter。
在这里插入图片描述

starter的使用(别说你不会)

1.在别的项目中引入依赖

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

2.配置yml或者properties

server:
  port: 8848
plusroax:
  address:
    enabled: true  # 开启才生效
    host: 127.0.0.1
    port: 8848

3.使用controller测试一下

我们引入的自己写的starter,已经把MyTemplete放入容器中了,可以直接用。

@RestController
@RequestMapping(value = "use")
public class UseController {

  @Autowired
  private MyTemplete myTemplete;

  @GetMapping(value = "print")
  public void print(){
      myTemplete.print();
  }
}

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以!以下是一个简单的示例,展示了如何手写一个Spring Boot Starter: 首先,创建一个 Maven 项目,并添加以下依赖项: ```xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.5.4</version> </dependency> </dependencies> ``` 接下来,创建一个自定义的自动配置类,用于配置你的 Starter: ```java @Configuration @EnableConfigurationProperties(MyStarterProperties.class) public class MyStarterAutoConfiguration { private final MyStarterProperties properties; public MyStarterAutoConfiguration(MyStarterProperties properties) { this.properties = properties; } // 在此处定义你的自动配置逻辑 @Bean public MyStarterService myStarterService() { return new MyStarterService(properties); } } ``` 然后,创建一个属性类,用于将外部配置绑定到属性上: ```java @ConfigurationProperties("my.starter") public class MyStarterProperties { private String message; // 提供 getter 和 setter } ``` 最后,创建一个自定义的服务类,该服务类将在你的 Starter 中使用: ```java public class MyStarterService { private final MyStarterProperties properties; public MyStarterService(MyStarterProperties properties) { this.properties = properties; } public void showMessage() { System.out.println(properties.getMessage()); } } ``` 现在,你的 Spring Boot Starter 已经准备就绪了!你可以将其打包并使用在其他 Spring Boot 项目中。在其他项目的 `pom.xml` 文件中,添加你的 Starter 依赖: ```xml <dependencies> <dependency> <groupId>com.example</groupId> <artifactId>my-starter</artifactId> <version>1.0.0</version> </dependency> </dependencies> ``` 然后,在你的应用程序中使用 `MyStarterService`: ```java @SpringBootApplication public class MyApplication implements CommandLineRunner { private final MyStarterService myStarterService; public MyApplication(MyStarterService myStarterService) { this.myStarterService = myStarterService; } public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } @Override public void run(String... args) throws Exception { myStarterService.showMessage(); } } ``` 这样,你就成功地创建了一个简单的 Spring Boot Starter!当其他项目引入你的 Starter 并运行时,将输出预定义的消息。 当然,这只是一个简单的示例,真实的 Starter 可能包含更多的配置和功能。你可以根据自己的需求进行扩展和定制。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值