一、什么是Spring Boot Starter

1.1 自动装配

在介绍Spring Boot Starter之前,我们需要了解一下Spring Boot的自动装配机制,因为Spring Boot Starter的实现依赖于Spring Boot的自动装配机制。

SpringBoot在程序初始化时可以根据classpath、property属性、context中实例、以及运行容器特征等各种动态条件,来按需初始化相应的bean,并注册到IOC容器中。

SpringBoot启动的时候通过@EnableAutoConfiguration注解找到META-INF/spring.factories配置文件中所有的自动配置类,并对其进行加载,而这些自动配置类的类名都是以AutoConfiguration结尾来命名的,它实际上就是一个javaConfig形式的Spring容器配置类,它们都有一个@EnableConfigurationPerperties的注解,通过这个注解启动XXXProperties命名的类去加载全局配置中的属性,如server.port,而XXXProperties通过@ConfigurationProperties注解将全局配置文件中的属性与自己的属性进行绑定。

1.2 Spring Boot Starter概念

Starter是Spring Boot中的一个非常重要的概念,Starter相当于模块,它能将模块所需的依赖整合起来并对模块内的Bean根据环境( 条件)进行自动装配。使用者只需要依赖相应功能的Starter,无需做过多的配置和依赖,Spring Boot就能自动扫描并加载相应的模块。

Spring Boot Starter它提供了一个自动化配置类,一般命名为 XXXAutoConfiguration ,在这个配置类中通过条件注解来决定一个配置是否生效;然后,它还会提供一系列的默认配置,也允许开发者根据实际情况自定义相关配置;最后,通过类型安全的属性注入将这些配置属性注入进来,新注入的属性会代替掉默认属性。

例如,如果想使用Spring和JPA访问数据库,只需要项目中包含spring-boot-starter-data-jpa 依赖项,就可以正常使用。已有的Spring Boot Starter有很多,常用的有:

  • spring-boot-starter:核心 starter,包括自动化配置支持,日志以及 YAML
  • spring-boot-starter-test:SpringBoot 测试相关的 starter
  • spring-boot-starter-web:构建 restful、springMVC 的 web应用程序的 starter
  • spring-boot-starter-security:使用 Spring Security 的 starter

二、Spring Boot Starter编写

2.1 编写步骤

编写Starter非常简单,与编写一个普通的Spring Boot应用没有太大区别:

  • 新建Maven项目,在项目的POM文件中定义使用的依赖;
  • 新建配置类,写好配置项和默认的配置值,指明配置项前缀;
  • 新建自动装配类,根据 @Conditional注解的条件,使用@Configuration和@Bean来进行自动装配;
  • 新建spring.factories文件,指定Starter的自动装配类;
  • 编写服务类,也就是我们starter要实现的功能;

2.2 案例

新建maven项目,配置pom文件:

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.goldwind.example</groupId>
    <artifactId>spring-boot-starter-helloworld</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-starter-helloworld</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
        </dependency>

        <!-- 核心 starter,包括自动化配置支持,日志以及 YAML -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!-- 其中 spring-boot-configuration-processor 的作用是编译时生成 spring-configuration-metadata.json ,
        此文件主要给IDE使用。如当配置此jar相关配置属性在 application.yml ,你可以用ctlr+鼠标左键点击属性名,IDE会跳转
        到你配置此属性的类中。 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <!--  spring boot 测试相关的 starter   -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>


</project>
View Code

这里顺带提一下spring-boot-stater-parent,

spring-boot-starter-parent 主要有如下作用:

  • 定义了 Java 编译版本。
  • 使用 UTF-8 格式编码。
  • 继承自 spring-boot-dependencies,这个里边定义了依赖的版本,也正是因为继承了这个依赖,所以我们在写依赖时才不需要写版本号。
  • 执行打包操作的配置。
  • 自动化的资源过滤。
  • 自动化的插件配置。
  • 针对 application.properties 和 application.yml 的资源过滤,包括通过 profile 定义的不同环境的配置文件,例如 application-dev.properties 和 application-dev.yml。

新建配置类HelloWorldProperties.java:

package com.goldwind.example;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * 新建配置类,写好配置项和默认的配置值,指明配置项前缀
 *
 * @author zy
 * @since 2021/9/22
 */
@Data
@ConfigurationProperties(prefix = "example")
public class HelloWorldProperties {
    // 姓名
    private String name = "zy";

    // 年龄
    private Integer age = 18;
}

新建自动装配类HelloWorldAutoConfiguration.java:

package com.goldwind.example;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 新建自动装配类,使用@Configuration和@Bean来进行自动装配
 *
 * @author zy
 * @since 2021/9/22
 */
@Configuration
@ConditionalOnClass(HelloWorldService.class)
@EnableConfigurationProperties(HelloWorldProperties.class)
public class HelloWorldAutoConfiguration {
    @Autowired
    private HelloWorldProperties properties;

    @Bean
    @ConditionalOnMissingBean
    public HelloWorldService starterService() {
        return new HelloWorldService(properties);
    }
}

新建spring.factories(resources/META-INF路径下):

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.goldwind.example.HelloWorldAutoConfiguration

编写服务类HelloWorldService.java:

package com.goldwind.example;

/**
 * 编写服务类,也就是我们starter要实现的功能
 * 输出配置文件中的信息
 *
 * @author zy
 * @since 2021/9/22
 */
public class HelloWorldService {
    private HelloWorldProperties properties;

    /**
     * 构造函数
     */
    public HelloWorldService(HelloWorldProperties properties) {
        this.properties = properties;
    }

    public void helloWorld() {
        System.out.println(String.format("我的名字是%s,我今年%d岁", properties.getName(), properties.getAge()));
    }
}

执行mvn install,生成spring-boot-starter-helloworld.jar。

三、引用Starter

3.1 步骤

  • 将Starter项目的依赖添加到我们自己的spring boot项目中;
  • 在application.yml配置文件中添加配置信息;

3.2 案例

新建maven项目,配置pom文件:

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.goldwind.example</groupId>
    <artifactId>spring-boot-starter-helloworld-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

        <dependency>
            <groupId>com.goldwind.example</groupId>
            <artifactId>spring-boot-starter-helloworld</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

新建DemoRunner.java:

package com.goldwind.example;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

/**
 * 通过实现ApplicationRunner或CommandLineRunner接口,可以实现应用程序启动完成后自动运行run方法
 *
 * @author zy
 * @since 2021/9/22
 */
@Component
public class DemoRunner implements ApplicationRunner {
    @Autowired
    private HelloWorldService helloWorldService;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        helloWorldService.helloWorld();
    }
}

新建DemoApplication.java:

package com.goldwind.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

修改配置文件application.yml:

example:
  name: sf
  age: 28

四、源码

spring-boot-starter-helloworld

spring-boot-starter-helloworld-demo

相关文章:

  • 2022-12-23
  • 2022-01-15
  • 2021-04-15
  • 2021-08-14
  • 2022-02-22
  • 2021-06-24
  • 2022-02-17
  • 2021-08-16
猜你喜欢
  • 2021-10-21
  • 2022-01-03
  • 2021-11-09
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-04-02
相关资源
相似解决方案