• Spring Boot -- Spring Boot Starter的简单实现


    一、什么是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

  • 相关阅读:
    Django + Uwsgi + Nginx 的概念
    ubantu+nginx+uwsgi+django部署
    FileZilla以root用户登录Linux
    全文检索django-haystack+jieba+whoosh
    七牛云上传视频
    JWT登录与多方式登录
    vue绑定用户页面
    绑定微博用户接口
    vue微博回调空页面
    微博回调接口
  • 原文地址:https://www.cnblogs.com/zyly/p/15379585.html
Copyright © 2020-2023  润新知