springboot-starter定制-Drools模块封装

前言

  • 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包,开始自动配置

自动配置流程

  • 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类 * n
  • XxxProperties类 * 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
  • 原文地址,欢迎交流
posted @ 2020-09-15 14:25  summaster  阅读(579)  评论(0编辑  收藏  举报