前言
- springboot-starter其实就是某个功能点的依赖和配置的集合
- 对于springboot应用,starter的使用大大简洁了依赖结构,并且实现了功能性的配置可拔插。
- springboot项目中,我们已经到处用到了starter:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
- 比如我们需要开发webmvc时,只需要添加 spring-boot-starter-web的jar包依赖即可。这样的话,我们不用再需要注意
SpringMVC
的开发过程中还需那些依赖 - 本篇将在前面drools-springboot工程的基础上将drools核心部分抽成starter,以供各种springboot工程直接依赖使用。
springboot-starter与自动配置原理
springboot的应用启动
- 一切起点是
SpringApplication.run(...)
- 从自动配置角度,可将启动过程分两大步
- 根据类路径是否存在特征类,决定是否Web环境,从而创建相应类型的
ApplicationContext
SpringFactoriesLoader
扫描所有具有META-INF/spring.factories
的jar包,开始自动配置
- 根据类路径是否存在特征类,决定是否Web环境,从而创建相应类型的
自动配置流程
SpringBoot
启动类头上的@SpringBootApplication
注解集成了@EnableAutoConfiguration
注解,这个注解又import
AutoConfigurationImportSelector
类。SpringApplication.run(...)
执行后会通过AutoConfigurationImportSelector.selectImports()
扫描对应jar包下的META-INF/spring.factories
配置文件,并加载其中对应注解全类名(Key)的诸多的XxxAutoConfiguration
自动配置类(值列表)。XxxAutoConfiguration
自动配置类它实际上就是一个个的JavaConfig
形式的SpringIOC
容器配置类,它能通过XxxProperties
类取得在全局配置文件中配置的属性,如:server.port
。XxxProperties
类是通过@ConfigurationProperties
注解与全局配置文件中对应的属性进行绑定的。
springboot-starter到自动配置
从本质上看,一个starter
其实就是一个专项jar 包和配置集合,配合SpringBoot
自动配置使用。
所以这个大的jar包中,得有springboot自动配置约定的四大要素:
resources/META-INF/spring.factories
XxxAutoConfiguration
类 * nXxxProperties
类 * n- 专项服务的jar包依赖 * n
那么,自定义自己的starter就是构建上面四个要素,并形成jar依赖以供使用。
开始定制drools-starter
这里开始,将会把前面文章中的drools-springboot工程一步步转化为richard-drools-starter,然后简单进行依赖测试。
- 新建drools-starter的maven工程,依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-decisiontables</artifactId> </dependency>
- 创建
AppDroolsConfigProperties
类,对应本功能模块的yml配置项,可以有默认配置@ConfigurationProperties(prefix = "app.drools") //@Component @Data public class AppDroolsConfigProperties { /** * 是否启用配置bean */ private boolean enable = false; /** * 加载类型,cp-类路径下扫描规则文件-默认,xls-外置路径读取,db-数据库查询规则定义-待集成 */ private String loadType = "cp"; /** * 类路径目录,默认是 resources/rules 下所有的.drl文件 */ private String cpDir = "rules"; /** * 外置xls文件列表路径,比如 D:/temp/xxx.xls */ private List<String> xlsFilePaths = new ArrayList<>(); }
- 创建
AppDroolsAutoConfiguration
自动配置类,注意搭配Properties的属性决定是否IOC化Bean,实现配置热拔插(enable属性)@ConditionalOnProperty(prefix = "app.drools",name = "enable", havingValue = "true") @EnableConfigurationProperties(AppDroolsConfigProperties.class) @Configuration public class AppDroolsAutoConfiguration { @Bean @ConditionalOnMissingBean(KieUtilService.class) public KieUtilService getKieUtilService() { return new KieUtilService(); } }
KieUtilService
则和原来的差不多,是外部@Autowired
的服务类- 创建自动化配置文件
resources/META-INF/spring.factories
(自动配置扫描和yml配置提示),本示例较简单,只有一个自动配置内,.factories内容如下:org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.richard.demo.drools.starter.AppDroolsAutoConfiguration
- 执行
mvn install
安装jar包 - 完成
drools-starter依赖测试
- 新建Maven工程
drools-starter-test
,pom依赖:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>cn.richard.demo</groupId> <artifactId>drools-starter</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
- yml配置,先不加入starter中的配置
server: port: 8000 spring: application: name: @project.artifactId@ profiles: active: local thymeleaf: cache: false
- 启动工程,可以发现starter中的IOC-Bean并不会被初始化
- 现在加入专项配置,此时starter中的XXXProperties属性也可以被代码提示了
server: port: 8000 spring: application: name: @project.artifactId@ profiles: active: local thymeleaf: cache: false app: drools: enable: true load-type: xls xls-file-paths: - D:/temp/tax.xls
- 重启应用(相关文件见前几篇),看日志可以发现本次的starter的Service已经注入IOC
- 功能测试
- 打完收工
小结
- Drools系列的总结先告一段落,回顾:
- 从类路径简单加载.drl文件
- -> 从数据库加载.drl文本和动态刷新
- -> 利用Nacos解决多节点动态刷新
- -> 决策表的使用
- -> starter化
- 这几篇笔记,正是最近笔者所在项目中的应用的过程记录,还是那句话:脱离实际场景谈技术都是纸上谈兵!
- 本次demo源码,欢迎star-chat
- 原文地址,欢迎交流