SpringBoot的starter到底是什么?

我们都知道,Spring的功能非常强大,但也有些弊端。比如:我们需要手动去配置大量的参数,没有默认值,需要我们管理大量的jar包和它们的依赖。,为了提升Spring项目的开发效率,简化一些配置,Spring官方引入了SpringBoot。,当然,引入SpringBoot还有其他原因,在这里就不过多描述了。,本文重点跟大家一起聊聊SpringBoot的starter机制,因为它太重要了。,图片,在SpringBoot还没有出来之前,我们使用Spring开发项目。如果程序需要连接数据库,我们一般会使用Hibernate或Mybatis等ORM框架,这里我以Mybatis为例,具体的操作步骤如下:,当然有些朋友可能会指正,不是还需要引入数据库驱动包吗?,确实需要引入,但数据库驱动有很多,比如:mysql、oracle、sqlserver,这不属于mybatis的范畴,使用者可以根据项目的实际情况单独引入。,如果程序只是需要连接数据库这一个功能还好,按上面的步骤做基本可以满足需求。但是,连接数据库可能只是庞大的项目体系中一个环节,实际项目中往往更复杂,需要引入更多的功能,比如:连接redis、连接mongodb、使用rocketmq、使用excel功能等等。,引入这些功能的话,需要再把上面的步骤再重复一次,工作量无形当中增加了不少,而且有很多重复的工作。,另外,还是有个问题,每次到要到maven中找合适的版本,如果哪次找的mybatis.jar包 和 mybatis-spring.jar包版本不兼容,程序不是会出现问题?,SpringBoot为了解决以上两个问题引入了starter机制。,我们首先一起看看mybatis-spring-boot-starter.jar是如何定义的。,图片,可以看到它的META-INF目录下只包含了:,注意一下,没有一行代码。,我们重点看一下pom.xml,因为这个jar包里面除了这个没有啥重要的信息。,从上面可以看出,pom.xml文件中会引入一些jar包,其中除了引入spring-boot-starter,之外重点看一下:mybatis-spring-boot-autoconfigure。,我们找到mybatis-spring-boot-autoconfigure.jar文件,打开这个文件。,图片,里面包含如下文件:,spring-configuration-metadata.json和additional-spring-configuration-metadata.json的功能差不多,我们在applicationContext.properties文件中输入spring时,会自动出现下面的配置信息可供选择,就是这个功能了。,图片,来自灵魂的一问:这两个文件有什么区别?,答:如果pom.xml中引入了spring-boot-configuration-processor包,则会自动生成spring-configuration-metadata.json。,如果需要手动修改里面的元数据,则可以在additional-spring-configuration-metadata.json中编辑,最终两个文件中的元数据会合并到一起。,MybatisProperties类是属性实体类:,可以看到Mybatis初始化所需要的很多属性都在这里,相当于一个JavaBean。,下面重点看一下MybatisAutoConfiguration的代码:,这个类就是一个Configuration(配置类),它里面定义很多bean,其中最重要的就是SqlSessionFactory的bean实例,该实例是Mybatis的核心功能,用它创建SqlSession,对数据库进行CRUD操作。,除此之外,MybatisAutoConfiguration类还包含了:,这些注解都是一些辅助功能,决定Configuration是否生效,当然这些注解不是必须的。,接下来,重点看看spring.factories文件有啥内容:,里面只有一行配置,即key为EnableAutoConfiguration,value为MybatisAutoConfiguration。,好了,介绍了这么多东西,现在我们来总结一下。,starter几个要素如下图所示:,图片,那么,编写starter需要哪些步骤?,我们试着按照这四步,自己编写一个starter看看能否成功,验证一下总结的内容是否正确。,该项目名称为id-generate-starter,注意为了方便我把项目重命名了,原本应该是叫id-generate-spring-boot-starter的,如下图所示:,图片,pom.xml文件定义如下:,我们看到,它只引入了id-generate-spring-boot-autoconfigure。当然如果有需要这里还可以引入多个autoconfigure或者多个其他jar包或者。,同样为了方便我把项目重命名了,原本是叫id-generate-spring-boot-autoconfigure,如下图所示:,图片,该项目当中包含:pom.xml、spring.factories、IdGenerateAutoConfiguration、IdGenerateService 和 IdProperties 这5个关键文件,下面我们逐一看看。,先从pom.xml,我们可以看到,这个文件比较简单就引入了:,重点看看spring.factories文件:,它里面只包含一行配置,其中key是EnableAutoConfiguration,value是IdGenerateAutoConfiguration。,再重点看一下IdGenerateAutoConfiguration。,该类是一个使用了@Configuration注解标记为了配置类,生效的条件是@ConditionalOnClass注解中检测到包含IdProperties.class。并且使用@EnableConfigurationProperties注解会自动注入IdProperties的实例。,此外,最关键的点是该类里面创建了idGenerateService的bean实例,这是自动配置的精髓。,再看看IdGenerateService。,我们可以看到它是一个普通的类,甚至都没有使用@Service注解,里面有个generate方法,根据workId的值和随机数动态生成id。,最后看看IdProperties。,它是一个配置实体类,里面包含了相关的配置文件。使用@ConfigurationProperties注解,会自动把application.properties文件中以sue开通的,参数名称跟IdProperties中一样的参数值,自动注入到IdProperties对象中。,这个项目主要用于测试。,图片,该项目里面包含:pom.xml、application.properties、Application 和 TestRunner 文件。,先看看pom.xml文件,、由于只测试刚刚定义的id生成功能,所以只引入的id-generate-spring-boot-starter jar包。,application.properties配置资源文件。,只有一行配置,因为我们的IdProperties中目前只需要这一个参数。,Application是测试程序启动类。,很简单,就是一个普通的springboot启动类。,TestRunner是我们的测试类。,它实现了ApplicationRunner接口,所以在springboot启动的时候会调用该类的run方法。,好了,所有自定义starter的代码和测试代码都已经就绪。接下,运行一下Application类的main方法。,运行结果:,完美,验证成功了。,接下来,我们分析一下starter的底层实现原理。,通过上面编写自己的starter的例子,相信大家对starter的认识更进一步了,现在跟大家一起看看starter的底层是如何实现的。,id-generate-starter.jar其实是一个空项目,依赖于id-generate-autoconfiguration.jar。,id-generate-starter.jar是一个入口,我们给他取一个更优雅的名字:门面模式,其他业务系统想引入相应的功能,必须要通过这个门面。,我们重点分析一下 id-generate-autoconfiguration.jar。,该jar包核心内容是:IdGenerateConfiguration,这个配置类中创建了IdGenerateService对象,IdGenerateService是我们所需要自动配置的具体功能。,接下来一个最重要的问题: IdGenerateConfiguration为什么会自动加载的呢?,还记得我们定义的spring.factories文件不?,它里面只包含一行配置,其中key是EnableAutoConfiguration,value是IdGenerateAutoConfiguration。,要搞明白这个过程,要从Application类的@SpringBootApplication注解开始:,从上面可以看出该注解里面包含了@EnableAutoConfiguration注解。,@EnableAutoConfiguration注解会引入AutoConfigurationImportSelector类。,该类的selectImports方法一个关键方法:,这里就是starter能够自动配置的秘密。,此外,有些朋友看其他人定义的springboot starter可能会有疑惑。,先看看druid-spring-boot-starter。,图片,alibaba定义的druid-spring-boot-starter只有xxx-spring-boot-starter.jar文件,而没有xxx-spring-boot-autoconfigure.jar文件。,再看看spring-boot-starter-jdbc:,图片,更神奇的是这个文件中连pom.xml都没有,一脸懵逼。。。。。。。,是不是我讲错了?,答:其实没有。,SpringBoot的原则是约定优于配置。,从spring-boot-starter-jdbc内部空实现来看,它的约定是要把xxx-spring-boot-starter.jar和xxx-spring-boot-autoconfigure.jar区分开的。个人认为,alibaba定义得并不好,没有遵照springboot的约定,虽然功能不受影响。(这个地方欢迎一起探讨一下)。,而springboot自己定义的spring-boot-starter-jdbc为什么连pom.xml文件也没有呢?,它不需要依赖xxx-spring-boot-autoconfigure.jar文件吗?,因为springboot把所有的自动配置的类都统一放到spring-boot-autoconfigure.jar下面了:,图片,​spring.factories​文件内容如下:,图片,SpringBoot这样集中管理自动配置,而不需要从各个子包中遍历,我个人认为是为了查找效率。,我们最后再看看spring-cloud-starter-openfegin。,图片,明显看到,它是遵循了我们说的原则的。,除此之外,还有一个原则一顺便提一下。,SpringBoot和SpringCloud系列定义jar包的名称是:,而我们自己的项目定义的jar应该是:

文章版权声明

 1 原创文章作者:汇维网,如若转载,请注明出处: https://www.52hwl.com/16386.html

 2 温馨提示:软件侵权请联系469472785#qq.com(三天内删除相关链接)资源失效请留言反馈

 3 下载提示:如遇蓝奏云无法访问,请修改lanzous(把s修改成x)

 免责声明:本站为个人博客,所有软件信息均来自网络 修改版软件,加群广告提示为修改者自留,非本站信息,注意鉴别

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023年3月4日 下午11:59
下一篇 2023年3月6日 上午12:00