1. starter简介

:::tips SpringBoot 最强大的功能就是把我们常用的场景抽取成了一个个starter(场景启动器),我们通过引入springboot 为 我提供的这些场景启动器,我们再进行少量的配置就能使用相应的功能。即使是这样,springboot也不能囊括我们所有 的使用场景,往往我们需要自定义starter,来简化我们对springboot的使用。
:::

2. 如何自定义

2.1 Spring-boot自动装配规范 :::tips springboot的出现就是为了简化spring开发,提供开箱即用的手脚架功能.基于springboot自动装配原理手撸一个starterstarter
命名规范:

  • 官方命名格式:spring-boot-starter-模块名
  • 自定义命名规范:模块名-spring-boot-starter :::

    步骤

  • 创建项目:mck-spring-boot-starter

  • 引入pom依赖
  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-configuration-processor</artifactId>
  4. <optional>true</optional>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.projectlombok</groupId>
  8. <artifactId>lombok</artifactId>
  9. <optional>true</optional>
  10. </dependency>
  • 引入打包工具

    1. <build>
    2. <plugins>
    3. <plugin>
    4. <groupId>org.apache.maven.plugins</groupId>
    5. <artifactId>maven-compiler-plugin</artifactId>
    6. <configuration>
    7. <encoding>${project.build.sourceEncoding}</encoding>
    8. <source>${java.version}</source>
    9. <target>${java.version}</target>
    10. <showWarnings>true</showWarnings>
    11. </configuration>
    12. </plugin>
    13. </plugins>
    14. </build>
  • 编写MckProperties

  1. package com.itmck.mckspringbootstarter.config;
  2. import lombok.Data;
  3. import org.springframework.boot.context.properties.ConfigurationProperties;
  4. /**
  5. * 太阳当空照,花儿对我笑
  6. * <p>
  7. * Create by M ChangKe 2021/8/7 21:51
  8. **/
  9. @Data
  10. @ConfigurationProperties(prefix = "mck")
  11. public class MckProperties {
  12. private String nm;
  13. }
  • DesAopConfig
  1. package com.itmck.mckspringbootstarter.config;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  4. import org.springframework.boot.context.properties.EnableConfigurationProperties;
  5. import org.springframework.context.annotation.Configuration;
  6. @Configuration
  7. @EnableConfigurationProperties(MckProperties.class)
  8. @ConditionalOnProperty(
  9. prefix = "mck",
  10. name = "nm",
  11. havingValue = "true"
  12. )
  13. public class DesAopConfig {
  14. @Autowired
  15. MckProperties mckProperties;
  16. public String handler() {
  17. return mckProperties.getNm();
  18. }
  19. }
  • 创建resources\META-INF\spring.factories

:::info org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.itmck.mckspringbootstarter.config.DesAopConfig :::

  • 打包

:::info mvn clean install :::

使用starter步骤:

  • 引入依赖

    1. <dependency>
    2. <groupId>com.itmck</groupId>
    3. <artifactId>mck-spring-boot-starter</artifactId>
    4. <version>0.0.1-SNAPSHOT</version>
    5. </dependency>
  • application.yml

  1. mck:
  2. nm: true
  • java中引入如下:

    1. @Slf4j
    2. @Component
    3. public class Publisher {
    4. @Resource
    5. DesAopConfig desAopConfig;
    6. public void send() {
    7. log.info("desAopConfig nm:{}",desAopConfig.handler());
    8. }
    9. }
  • 运行结果如下

image.png

3.源码简述

:::tips 通过上面springboot自动装配的源码发现

  • AutoConfigurationImportSelector implements DeferredImportSelector
  • DeferredImportSelector extends ImportSelector :::

因为springboot通过一系列操作最终还是找到factories进行读取配置.但是从上面源码我们还可以直接通过使用 @Import 设置对应的类也是一样的所以还可以直接:
@Import({DesAopConfig.class}) 或者@Import({MyImportSelector.class})

注意,通过自定义类实现ImportSelector 重写 selectImports 方法可以注入多个

  • MyImportSelector ```java package com.itmck.mckspringbootstarter.init;

import com.itmck.mckspringbootstarter.config.DesAopConfig; import org.springframework.context.annotation.ImportSelector; import org.springframework.core.type.AnnotationMetadata;

/**

  • 太阳当空照,花儿对我笑
  • Create by M ChangKe 2021/8/7 19:26 **/ public class MyImportSelector implements ImportSelector {

    @Override public String[] selectImports(AnnotationMetadata annotationMetadata) {

    1. return new String[]{DesAopConfig.class.getName()};

    } } ```

  • 自定义注解
  1. package com.itmck.mckspringbootstarter.config;
  2. import com.itmck.mckspringbootstarter.init.MyImportSelector;
  3. import org.springframework.context.annotation.Import;
  4. import java.lang.annotation.*;
  5. /**
  6. * 太阳当空照,花儿对我笑
  7. * <p>
  8. * Create by M ChangKe 2021/8/7 22:01
  9. **/
  10. @Target(ElementType.TYPE)
  11. @Retention(RetentionPolicy.RUNTIME)
  12. @Documented
  13. @Inherited
  14. @Import({MyImportSelector.class})
  15. public @interface Mck {
  16. }
  • 启动类上开启注解 @Mck ```java @Mck @SpringBootApplication public class SpringbootMqApplication {

    public static void main(String[] args) {

    1. SpringApplication.run(SpringbootMqApplication.class, args);

    }

}

```

  • 运行同上

    4.DeferredImportSelector 与 ImportSelector 区别

    :::tips 延迟加载,分组,springboot通过实现延迟加载目的:如果类路径下存在用户自定义优先加载用户自定义. :::