Spring Boot Starter需要些什么

前面我们简单介绍了如何使用消息中间件 apache pulsar ,但是在项目中那样使用,显然是不太好的,不管从易用性和扩展性来看,都是远远不够, 为了和springboot项目集成,写一个pulsar-spring-boot-starter是非常有必要的,在此之前,我们先看看一个starter需要些什么。
spring boot starterspring-boot的强大之处在于其提供的大量starter组件,基本涵盖了我们开发中的各个技术领域,比如数据库访问有jdbc、jpa,缓存有redis,全文检索有elasticsearch,消息队列有amqp、kafka等等。
在项目中你只需要按需引入相应的依赖 spring-boot-starter-xxx ,然后只需要替换对应的配置参数即可,就能快速使用对应的功能,不得不说简直是为开发者插上了翅膀。
命名风格对于starter模块如何命名,spring官方是这样建议:
spring官方命名格式为:spring-boot-starter-{name}非spring官方建议命名格式:{name}-spring-boot-starter准备工作如果你之前有看过spring官方starter组件,你会发现主要是基于autoconfigure及@enable来实现的。
其中autoconfigure也就是我们常说的自动装配,在spring-boot-autoconfigure包中的目录/mete-inf/spring.factories对应文件中,你可以看到这样的配置:当启动spring boot项目时这些配置都会被加载(这么多的配置全部加载并处理,难怪启动那么慢)。
在starter中依赖的具体实现包中,一般都会提供一个@enable注解作为部分扩展功能的开关,我们可以在系统中通过该注解引入按需引入配置
autoconfigure配置的一定会被加载,而@enable有开发者选择使用使用,当然有些组件是没有autoconfigure,必须通过@enable来启用
下面我们先对这块内容做个简单的认识,方便后续在写具体starter时知道怎么写以及为什么那样写。
autoconfigure在目录中创建src/main/resources/mate-inf中创建文件spring.factories,定义springboot应用启动时的需要注册的配置,这个主要是基于spi机制来实现, 下面是当前spring-boot-autoconfigure中spring.factories文件的部分内容
# auto configureorg.springframework.boot.autoconfigure.enableautoconfiguration=org.springframework.boot.autoconfigure.admin.springapplicationadminjmxautoconfiguration,org.springframework.boot.autoconfigure.aop.aopautoconfiguration,org.springframework.boot.autoconfigure.amqp.rabbitautoconfiguration,org.springframework.boot.autoconfigure.batch.batchautoconfiguration,org.springframework.boot.autoconfigure.cache.cacheautoconfiguration,org.springframework.boot.autoconfigure.cassandra.cassandraautoconfiguration,org.springframework.boot.autoconfigure.context.configurationpropertiesautoconfiguration,org.springframework.boot.autoconfigure.context.lifecycleautoconfiguration,...配置在这里的带有@configuration的类(如果没有被conditional条件过滤掉)都会作为配置将相关bean注册到spring容器.
主要实现基于@springbootapplication注解上的注解@enableautoconfiguration
enable以spring aop相关的注解@enableaspectjautoproxy为例,我们看下 spring官方是怎么使用@enable注解来实现配置加载的:
@enableaspectjautoproxy
改注解除了一般注解的基础(@target、@retention)元素外,还包含了两个配置属性proxytargetclass、exposeproxy以及一个@import
@target(elementtype.type)@retention(retentionpolicy.runtime)@documented@import(aspectjautoproxyregistrar.class)public @interface enableaspectjautoproxy { boolean proxytargetclass() default false; boolean exposeproxy() default false;}@import
在@import中我们可以配置需要导入的配置类,有以下几个选择:
直接导入@configuration标识的类导入实现了接口importbeandefinitionregistrar的类,来向容器注册beandefinition导入实现了接口importselector的类(不需要@configuration)来选择配置@import(aspectjautoproxyregistrar.class)importbeandefinitionregistrar
在上面@enableaspectjautoproxy注解上,通过@import,引入了aspectjautoproxyregistrar,而该类又实现了接口importbeandefinitionregistrar, 该接口能够通过beandefinitionregistry向spring容器注册我们期望的beandefinition,看代码:
class aspectjautoproxyregistrar implements importbeandefinitionregistrar { @override public void registerbeandefinitions( annotationmetadata importingclassmetadata, beandefinitionregistry registry) { aopconfigutils.registeraspectjannotationautoproxycreatorifnecessary(registry); annotationattributes enableaspectjautoproxy = annotationconfigutils.attributesfor(importingclassmetadata, enableaspectjautoproxy.class); if (enableaspectjautoproxy != null) { if (enableaspectjautoproxy.getboolean(proxytargetclass)) { aopconfigutils.forceautoproxycreatortouseclassproxying(registry); } if (enableaspectjautoproxy.getboolean(exposeproxy)) { aopconfigutils.forceautoproxycreatortoexposeproxy(registry); } } }}这里我们可以拿到@enableaspectjautoproxy的元数据以及对应的属性配置,这样就可以基于开发者的配置实现不同逻辑
importselector
上面说到了,@import还可以配置实现了importselector接口的类,进而控制具体需要使用的configuration,下面是@enableasync中@import配置的类
public class asyncconfigurationselector extends advicemodeimportselector { private static final string async_execution_aspect_configuration_class_name = org.springframework.scheduling.aspectj.aspectjasyncconfiguration; @override @nullable public string[] selectimports(advicemode advicemode) { switch (advicemode) { case proxy: return new string[] {proxyasyncconfiguration.class.getname()}; case aspectj: return new string[] {async_execution_aspect_configuration_class_name}; default: return null; } }}importaware
同样和@import配合使用,针对基于importselector选择的configuration,只要实现了importaware接口,就可以拿到@import对应@enable注解的元数据
@configurationpublic abstract class abstractasyncconfiguration implements importaware { @override public void setimportmetadata(annotationmetadata importmetadata) { this.enableasync = annotationattributes.frommap( importmetadata.getannotationattributes(enableasync.class.getname(), false)); if (this.enableasync == null) { throw new illegalargumentexception( @enableasync is not present on importing class + importmetadata.getclassname()); } }}上面主要根据spring源代码中的例子,了解@enable、@import、importbeandefinitionregistrar、importselector、importaware如何搭配使用, 从而实现spring的动态配置,用一张关系图表示:
relation
其他扩展spring-boot-configuration-processor
我们知道springboot的配置我们都会写在application.yml(.properties)文件中,为了简化配置工作,如果能有智能提示就好了。这不,别人也想到了。只用这样做:
现在只需要在项目中引入依赖: org.springframework.boot spring-boot-configuration-processor true定义一个properties文件@data@configurationproperties(prefix = myprop)public class myproperties { private boolean enable; private string name;}在configuration中导入@configuration@enableconfigurationproperties({myproperties.class})public class webapiautoconfiguration { }打包mvn clean install生产metadata.json 可以看到,在jar中的/meta-inf目录下多了一个spring-configuration-metadata.json文件@conditional
实现spring bean的可插拔,我们可以基于属性、配置、类或者bean来控制配置(@configuration)是否生效,常见的有下面的这些:
conditionalonbean 容器存在bean时配置有效conditionalonclass classpath中有指定class时配置有效conditionalonmissingbean 容器不存在bean时配置有效conditionalonmissingclass classpath中没有指定class时配置有效conditionalonproperty 属性配置对应值成立时配置有效autoconfigure和@enable
autoconfigure是在spring.factories中配置了就会加载,但是可以通过@conditional让配置中的bean不生效;@enable需要显示地使用才能有效,且先于autoconfigure生效,从而可以配合@conditional来阻断autoconfigure的配置
结束语关于spring框架的学习后面会慢慢增多,我们会从原理到实践来介绍其功能,如果你有感兴趣的技术点或者开发中的问题,可以通过留言进行交流分享。

详解8通道可编程电容式触摸芯片工作原理以及应用领域
中国LED企业该如何应对专利战?
软中断与硬中断介绍
基于Blackfin的图像处理,及其性能与CMOS传感器中I
内存行业衰退 未来是否会恢复市场尚未可知
Spring Boot Starter需要些什么
龙芯中科与中科信息签订合作框架协议
孩子不爱阅读怎么办?让阿尔法蛋大蛋2.0成为他的专属主播
LVD太阳能电磁感应灯开发
煤气管道堵漏的治理方案
格兰仕变频空调助力节能降耗 满足不同用户的消费需求
为防止语音网络钓鱼攻击,韩国金融监管机构与SK电讯合作开发人工智能
苏州电信基于5G SA架构开通超级大带宽组网能力
如何实现烧结机轴头磨损的有效修复
JD-BQX6六要素超声波传感器对接云平台有哪些
第一台区块链智能手机联想S5,复合塑料板材盖板再添一员
哪些方法可以快速赚取比特币
美的集团完成空调器典型产品的碳足迹、减碳量评价等研究工作
2025建筑机器人产业价值将增长10倍超15亿元
刚刚,蔚来发布首款自研激光雷达芯片!10月量产!