如何开发自己的SpringBootStarter

我们在使用 Spring Boot 的过程中,往往都是在pom.xml里加了一系列的依赖,然后启支一个包含main方法的Application,一切就OK啦。给你我的感觉,就像是自己要动手做个菜,自己不再需要准备每一部分的原材料,直接购买包装好的一份菜的原料,下锅即可。

东风网站制作公司哪家好,找创新互联公司!从网页设计、网站建设、微信开发、APP开发、响应式网站开发等网站项目制作,到程序开发,运营维护。创新互联公司于2013年创立到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选创新互联公司

那我们详细看下,这份「包装好」的原料中,到底做了些什么。

添加Starter依赖

这里添加的依赖,除了我们之前在Maven中熟悉的之外,还有一些都是长这个样子:

名为xxx-starter,比如

 
 
 
 
  1.       org.springframework.boot
  2.       spring-boot-starter-web
  3.     org.mybatis.spring.boot
  4.     mybatis-spring-boot-starter
  5.     1.3.2

具体这些starter是怎么起作用的呢,他们什么时候开始工作的?

一切都要从入口处说起。我们以上面的starter为例,看到这个mybatis的starter,其对应的pom中,包含这些依赖

 
 
 
 
  1.     
  2.       org.springframework.boot
  3.       spring-boot-starter
  4.     
  5.     
  6.       org.springframework.boot
  7.       spring-boot-starter-jdbc
  8.     
  9.     
  10.       org.mybatis.spring.boot
  11.       mybatis-spring-boot-autoconfigure
  12.     
  13.     
  14.       org.mybatis
  15.       mybatis
  16.     
  17.     
  18.       org.mybatis
  19.       mybatis-spring
  20.     
  21.   

我们看到,相当于我们添加了一个Starter的依赖,其背后会引入许多其定义的其他依赖,通过 Maven 的传递依赖,这些都会被自动添加了进来。

自动配置

相比传统的依赖,我们看到其中包含这样一个:mybatis-spring-boot-autoconfigure,这也是每个Starter的秘密所在:「AutoConfigure」

它会在实现时,考虑应用中的其他部分因素,「推断」你所需要的 Spring 配置。

在Spring Boot中,我们***的感受是配置仿佛都被做好了,直接使用即可,这就是

spring-boot-autoconfigure. 每个starter都有一个名为spring.factories

的文件,存放在META-INF目录下,其中的内容类似下面这个样子:

 
 
 
 
  1. # Auto Configure
  2. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  3. org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration

所有需要自动配置的Class,都需要配置成key是EnableAutoConfiguration的。

我们来看类的内部

 
 
 
 
  1. @Configuration
  2. @ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
  3. @ConditionalOnBean({DataSource.class})
  4. @EnableConfigurationProperties({MybatisProperties.class})
  5. @AutoConfigureAfter({DataSourceAutoConfiguration.class})
  6. public class MybatisAutoConfiguration {

Class 之上, 有不少注解来标识,有几点需要关注的:

  • 其中有标准的 Spring 配置注解 @Configuration
  • 几个@ConditionalXX
  • 标识执行顺序的@AutoConfigureAfter

其中,@ConditionalOnClass 标识 SqlSessionFactory类存在时,执行该配置, @ConditionalOnBean标识DataSource Bean在 Spring Context时,执行配置。

这些spring.factories是怎么被识别的呢? 这就得夸下 Spring 的FactoriesLoader了。

看下官方文档说明

  • Auto-configuration classes are regular Spring {@link Configuration} beans. They are located using the {@link SpringFactoriesLoader} mechanism (keyed against this class).
  • Generally auto-configuration beans are {@link Conditional @Conditional} beans (most
  • often using {@link ConditionalOnClass @ConditionalOnClass} and
  • {@link ConditionalOnMissingBean @ConditionalOnMissingBean} annotations).

启动的时候,根据ClassLoader中的jar,扫描所有 spring.factories,将其中符合条件的过滤出来,执行对应的配置。重点可以关注下

 
 
 
 
  1. protected List getAutoConfigurationImportFilters() {
  2.        return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class,
  3.                this.beanClassLoader);
  4.    }
 
 
 
 
  1.            AutoConfigurationMetadata autoConfigurationMetadata) {
  2.         long startTime = System.nanoTime();
  3.         String[] candidates = StringUtils.toStringArray(configurations);
  4.         boolean[] skip = new boolean[candidates.length];
  5.         boolean skipped = false;
  6.         for (AutoConfigurationImportFilter filter : getAutoConfigurationImportFilters()) {
  7.             invokeAwareMethods(filter);
  8.             boolean[] match = filter.match(candidates, autoConfigurationMetadata);
  9.             for (int i = 0; i < match.length; i++) {
  10.                 if (!match[i]) {
  11.                     skip[i] = true;
  12.                     skipped = true;
  13.                 }
  14.             }
  15.         }
  16.         if (!skipped) {
  17.             return configurations;
  18.         }
  19.         List result = new ArrayList<>(candidates.length);
  20.         for (int i = 0; i < candidates.length; i++) {
  21.             if (!skip[i]) {
  22.                 result.add(candidates[i]);
  23.             }
  24.         }
  25.         return new ArrayList<>(result);
  26.     }
  27. public String[] selectImports(AnnotationMetadata annotationMetadata) {
  28.         if (!isEnabled(annotationMetadata)) {
  29.             return NO_IMPORTS;
  30.         }
  31.         AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
  32.                 .loadMetadata(this.beanClassLoader);
  33.         AnnotationAttributes attributes = getAttributes(annotationMetadata);
  34.         List configurations = getCandidateConfigurations(annotationMetadata,
  35.                 attributes);
  36.         configurations = removeDuplicates(configurations);
  37.         Set exclusions = getExclusions(annotationMetadata, attributes);
  38.         checkExcludedClasses(configurations, exclusions);
  39.         configurations.removeAll(exclusions);
  40.         configurations = filter(configurations, autoConfigurationMetadata);
  41.         fireAutoConfigurationImportEvents(configurations, exclusions);
  42.         return StringUtils.toStringArray(configurations);
  43.     }

经过这里的执行之后, filter方法把符合条件的过滤出来了。

创建自定义Starter

经过上面两步,我们大概知道 Starter的工作原理。有时候,我们需要对外提供一些工具组件时,也想以 Starter 的形式提供出来,供别人使用。步骤也还算清晰,照葫芦画瓢。

  • 先创建自己的模块
  • 增加需要用到的依赖
  • 创建对应的 AutoConfiguration类
  • 创建META-INF/spring.factories 文件

此时,就不需要再将 Spring Boot 做为 Parent依赖,在单独的依赖中增加

 
 
 
 
  1.          org.springframework.boot
  2.          spring-boot-autoconfigure
  3.          2.0.6.RELEASE
  4.      
  5.      
  6.          org.springframework.boot
  7.          spring-boot-starter
  8.          2.0.6.RELEASE
  9.      

AutoConfiguration类也简单,照上面的创建一个

 
 
 
 
  1. @Configuration
  2. @ConditionalOnClass(HelloService.class)
  3. public class HelloServiceAutoConfiguration {

然后,增加文件

 
 
 
 
  1. org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.demo.HelloServiceAutoConfiguration

在需要这个服务的地方,直接引入依赖就OK啦。

【本文为专栏作者“侯树成”的原创稿件,转载请通过作者微信公众号『Tomcat那些事儿』获取授权】

当前题目:如何开发自己的SpringBootStarter
标题网址:http://www.gawzjz.com/qtweb2/news22/20422.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联