0

SpringBoot Starter缘起 - 大兴神

 1 year ago
source link: https://www.cnblogs.com/soker/p/16837521.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

SpringBoot通过SpringBoot Starter零配置自动加载第三方模块,只需要引入模块的jar包不需要任何配置就可以启用模块,遵循约定大于配置的思想。
那么如何编写一个SpringBoot Starter呢?我们需要考虑如下几个问题:

  1. 如何让SpringBoot发现我们编写的模块?
  2. 如何让模块读取SpringBoot的配置文件?
  3. 如果用户没有在配置文件中配置必要的配置项,如何默认禁用模块?
  4. 如何让SpringBoot知道模块有哪些配置项目,方便用户配置配置文件?

一.模块的发现

由于SpringBoot默认的包扫描路径是主程序所在包及其下面的所有子包里面的组件,引入的jar包下的类是不会被扫描的。那么如何去加载Starter的配置类呢?
SpringBoot约定会扫描Starter jar包META-INF目录下的spring.factories文件,只需要在spring.factories文件里配置要加载的类就可以了。下面的是Arthas的配置文件(arthas-spring-boot-starter-3.6.3.jar,Arthas是Alibaba开源的Java诊断工具。)。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.alibaba.arthas.spring.ArthasConfiguration,\ com.alibaba.arthas.spring.endpoints.ArthasEndPointAutoConfiguration

这样SpringBoot在启动的时候就会自动加载这些类存放到容器中管理。

二.模块读取SpringBoot的配置文件

ArthasConfiguration的源码:

@ConditionalOnProperty(
    name = {"spring.arthas.enabled"},
    matchIfMissing = true
)
@EnableConfigurationProperties({ArthasProperties.class})
public class ArthasConfiguration {
    @ConfigurationProperties(
        prefix = "arthas"
    )
    @ConditionalOnMissingBean(
        name = {"arthasConfigMap"}
    )
    @Bean
    public HashMap<String, String> arthasConfigMap() {
        return new HashMap();
    }

    @ConditionalOnMissingBean
    @Bean
    public ArthasAgent arthasAgent(@Autowired @Qualifier("arthasConfigMap") Map<String, String> arthasConfigMap, @Autowired ArthasProperties arthasProperties) throws Throwable {
        arthasConfigMap = StringUtils.removeDashKey(arthasConfigMap);
        ArthasProperties.updateArthasConfigMapDefaultValue(arthasConfigMap);
        String appName = this.environment.getProperty("spring.application.name");
        if (arthasConfigMap.get("appName") == null && appName != null) {
            arthasConfigMap.put("appName", appName);
        }

        Map<String, String> mapWithPrefix = new HashMap(arthasConfigMap.size());
        Iterator var5 = arthasConfigMap.entrySet().iterator();

        while(var5.hasNext()) {
            Map.Entry<String, String> entry = (Map.Entry)var5.next();
            mapWithPrefix.put("arthas." + (String)entry.getKey(), entry.getValue());
        }

        ArthasAgent arthasAgent = new ArthasAgent(mapWithPrefix, arthasProperties.getHome(), arthasProperties.isSlientInit(), (Instrumentation)null);
        arthasAgent.init();
        logger.info("Arthas agent start success.");
        return arthasAgent;
    }
}

我们发现类上面两个注解EnableConfigurationProperties和ConditionalOnProperty。这两个注解的作用如下:

  • EnableConfigurationProperties用来指定要加载的配置类,配置类用来加载SpringBoot的配置文件,SpringBoot配置文件中可以指定Arthas的启动参数。如果你不需要任何参数,则可以不指定EnableConfigurationProperties。
@ConfigurationProperties(
    prefix = "arthas"
)
public class ArthasProperties {
private String ip;
    private int telnetPort;
    private int httpPort;
    private String tunnelServer;
    private String agentId;
    private String appName;
    private String statUrl;
}
  • ConditionalOnProperty通过读取SpringBoot配置文件的指定参数判断是否启用组件,如果判断为False,ArthasConfiguration里的Bean就不会被加载到容器中,即组件的开关。Arthas读取spring.arthas.enabled来判断是否加载组件。如果你想默认启动,没有开关,则可以不指定ConditionalOnProperty。

三.编写自己的Starter

我们写个简单的Starter,不加载配置文件,并且默认启动的Starter。IDE用的是是IDEA社区版。

3.1创建一个SpringBootStarter项目

3.1.1 新建项目,选择使用Maven构建。
image
3.1.2 然后创建spring.factories文件和配置类。
image
3.1.3 spring.factories写入配置类的全称。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.bjgoodwil.SpringBootStarterConfiguration

3.1.4 Maven打包

使用Maven的site命令打包jar到自己的本地仓库中。

3.2在SpringBoot项目中引入jar

打开一个SpringBoot项目,在pom文件中引入Jar(直接拷贝Starter pom文件中的参数),启动SpringBoot项目,控制台就会打印配置类的打印语句。

<!--自定义Starter-->
<dependency>
    <groupId>com.bjgoodwill</groupId>
    <artifactId>springbootstarter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

本文作者:大兴神

本文链接:https://www.cnblogs.com/soker/p/16837521.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK