spring-boot-starter的关键、编写示例

笔者语录 话不多说,直接开干。


spring-boot-starter的关键

@SpringBootApplication注解源码是这样的:
在这里插入图片描述
  @ComponentScan注解的作用是把(@SpringBootApplication所在的)入口类所在的包(及其子包)下的所有被@Component注解(或拓展了@Component的注解)标记了的bean注册到spring容器中。那么,处于@ComponentScan扫描范围外的bean是如何注册到容器中的呢,那就是靠@EnableAutoConfiguration来实现注册的
  @EnableAutoConfiguration注解的作用是:将普通jar包资源目录下的META-INF/spring.factories文件里面配置的键为org.springframework.boot.autoconfigure.EnableAutoConfiguration的类纳入考虑范围内,考虑是否将这个(些)类注册进Spring容器。如果这个(些)类被@Component注解(或拓展了@Component的注解)标记了,且满足@Conditional…条件(如果有@Conditional…的话),那么将其注册进Spring容器,如果不满足条件,那么就不注册进Spring容器。
在这里插入图片描述

  • 注:追踪源码可知,在@EnableAutoConfiguration注解里面启用了SpringBoot的AutoConfigurationImportSelector类, 在AutoConfigurationImportSelector类中的getAutoConfigurationEntry方法里,调用了Spring的SpringFactoriesLoader#loadFactories来加载资源jar包下的META-INF/spring.factories文件里的key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的value集合
  • 注:@Conditional…条件有:
    在这里插入图片描述

编写spring-boot-starter(示例)

提示 artifactId的命名需要注意,spring-boot-starter-xxx是SpringBoot官方保留的starter命名方式;业界自定义的starter的命名,一般用xxx-spring-boot-starter

第一步创建一个SpringBoot项目,并简单改造

  1. 在pom.xml中引入spring-boot-configuration-processor和spring-boot-autoconfigure(完整pom.xml见下方)。
  2. 去掉pom.xml中的打可执行的jar包的插件(完整pom.xml见下方)。在这里插入图片描述
    注:普通的jar包与可执行的jar包的class文件路径是不一样的。
    注:只要去掉这个打包插件就行;去不去掉SpringBoot的启动类都没关系,不过出于洁癖考虑,推荐同时去掉启动类。
    注:这里 给出完整的pom.xml:
    <?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.2.6.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.pingan</groupId>
        <artifactId>custom-spring-boot-starter</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>custom-spring-boot-starter</name>
        <description>编写spring-boot-starter</description>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-configuration-processor</artifactId>
                <optional>true</optional>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-autoconfigure</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
        </dependencies>
    
    </project>
    

第二步编写“管理”类。这个类用来管理:启用哪些被@ConfigurationProperties标记了的类、注册哪些Bean等等

import com.pingan.customstarter.service.LogicHandler;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * starter管理类
 *
 * @author JustryDeng
 * @date 2020/4/4 14:48:27
 */
@Configuration
@EnableConfigurationProperties(CustomAutoConfiguration.Properties.class)
@ConditionalOnProperty(value = "coder.info.enabled", havingValue = "true")
public class CustomAutoConfiguration {

    @Bean
    public LogicHandler logicHandler() {
        return new LogicHandler();
    }

    /**
     * 配置信息
     *
     * @author JustryDeng
     * @date 2020/4/4 14:38:05
     */
    @Setter
    @Getter
    @ConfigurationProperties(prefix = "coder.info")
    public static class Properties {

        /** 是否启用 */
        private boolean enabled = false;

        /** 姓名 */
        private String name;

        /** 爱好 */
        private String motto;
    }
}

注:这个管理类不是必须的。如果不创建这个管理类来统一管理那些可能需要注册进容器的类的话,那么就需要在第四步(见下文)的spring.factories文件里,指定这些类了;无疑,创建管理类更方便,更利于维护。

第三步编写一个业务逻辑相关的类(见:第二步注册进Spring的那个bean),用来做需要的逻辑在这里插入图片描述

第四步在资源目录下的META-INF/spring.factories文件(无则创建)里,通过org.springframework.boot.autoconfigure.EnableAutoConfiguration指定要注册进容器的类

注:指定后,这个类不是说一定会被注册进容器,其必须被@Component注解(或拓展了@Component的注解)标记了,并且如果其有@Conditional…条件的话,那么还需要满足条件,才会被注册进Spring容器。
注:如果需要注册多个类,那么使用逗号隔开,如:在这里插入图片描述

第五步mvn install到本地仓库(,mvn deploy到远程仓库),供其它项目使用


测试一下

  • 第一步: 创建一个新的SpringBoot项目,并在pom.xml中,引入我们编写的starter。在这里插入图片描述
  • 第二步: 在application.yml中配置参数,使触发启动starter中的配置类。在这里插入图片描述
  • 第三步: 编写测试代码,并测试。
    在这里插入图片描述
  • 启动项目,控制台输出:
    在这里插入图片描述

由此可见,自定义spring-boot-starter成功!


^_^ 如有不当之处,欢迎指正

^_^ 参考链接
                       https://www.cnblogs.com/yuansc/p/9088212.html
                       https://www.cnblogs.com/softidea/p/6886460.html

                       https://blog.csdn.net/SkyeBeFreeman/article…

^_^ 参考资料
        《Spring Boot Cookbook》

^_^ 测试代码托管链接
         https://github.com/JustryDeng/…spring-boot-starter…

^_^ 本文已经被收录进《程序员成长笔记(二)》,笔者JustryDeng

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章