对比springboot官方插件和自定义插件,差异竟然是。。。

原创 积木 编程阁楼 6天前

以前的文章中,我们聊过springboot自定义插件《定制一个属于自己的spring boot starter》,定制过程还是蛮简单的,我们简单回顾下当时定制的脱敏插件的代码结构,如下:
➜  spring-boot-starter-sensitive git:(master) tree.├── pom.xml├── spring-boot-starter-sensitive.iml└── src│   ├── main│   │   ├── java│   │   │   └── cn│   │   │       └── gov│   │   │           └── zcy│   │   │               └── sensitive│   │   │                   ├── HttpFileKWSeekerProcessor.java│   │   │                   ├── KWSeekerAutoConfigration.java│   │   │                   ├── SeekerFactory.java│   │   │                   ├── SimpleKWSeekerProcessor.java│   │   │                   ├── conf│   │   │                   │   ├── Config.java│   │   │                   │   └── SensitiveConfigProperties.java│   │   │                   ├── core│   │   │                   │   ├── KWSeeker.java│   │   │                   │   └── KWSeekerManage.java│   │   │                   ├── model│   │   │                   │   ├── KeyWord.java│   │   │                   │   └── SensitiveWordResult.java│   │   │                   ├── processor│   │   │                   │   ├── AbstractFragment.java│   │   │                   │   ├── AdaptiveProcessor.java│   │   │                   │   ├── HTMLFragment.java│   │   │                   │   ├── IgnoreFragment.java│   │   │                   │   ├── Processor.java│   │   │                   │   └── WordFinder.java│   │   │                   └── util│   │   │                       ├── AnalysisUtil.java│   │   │                       ├── EmojiUtil.java│   │   │                       └── EndTagUtil.java│   │   └── resources│   │       ├── sensitive-word-single.properties│   │       └── sensitive-word.properties│   │       └── META-INF│   │           └── spring.factories│   └── test│       └── java│           ├── KWSeekerManageTest.java│           └── KwSeekerManageOSSTest.java
其中有3个关键的信息:
  1. pom.xml依赖配置文件
  2. spring SPI扩展文件spring.factories
  3. autoconfig自动扫描类
一切看起来都是这样的美好,我们可以开开心心去玩耍了。
但是,突然有一天,当你打开springboot官方插件时,似乎一下子又颠覆了认知。下面我们来看个web开发非常常用的spring-boot-starter-web这个官方插件的代码接口。
➜  spring-boot-starter-web tree.└── META-INF    ├── MANIFEST.MF    └── spring.provides1 directory, 2 files
什么?只有区区的两个文件?
  • MANIFEST.MF

Manifest-Version: 1.0Implementation-Title: Spring Boot Web StarterAutomatic-Module-Name: spring.boot.starter.webImplementation-Version: 2.0.3.RELEASEBuilt-By: SpringCreated-By: Apache Maven 3.5.3Build-Jdk: 1.8.0_141
  • spring.provides

provides: spring-webmvc,spring-web
本例中MANIFEST.MF文件中仅仅有一些基本的包信息,对于插件加载不会有什么作用。spring.provides又是做什么的呢,带着这个疑问,小编搜索了下springboot的issue,果然找到了答案。

spring.providers作用分析

地址:https://github.com/spring-projects/spring-boot/issues/1926
大致意思是STS工具会根据此文件的内容提示开发者依赖包信息。STS(Spring Tool Suit)是Spring 的开发工具,在 eclipse 的基础上做了些优化,初衷是想让开发 spring 项目时更爽。

题外话:为什么STS没有像spring框架一样流行起来?

因为spring远不等于java的全部啊,况且很多程序员都已经不适用spring框架了。作为程序员,IDE只是个工具,只要你对操作熟悉,快捷键熟悉,界面的设计又符合你的习惯和审美,理论上使用任何一款IDE都是OK的。当然出于规范化的要求,也有公司要求统一IDE的,这都无可厚非,idea的高效和便捷是sts比拟不了的。

说到这里,我们也知道了spring.providers这个文件对插件加载也没有任何的作用。这是怎么回事?

要说清楚这个问题,我们就要知道spring-boot-starter的作用,其作用本质上说不外乎以下两点:
  1. 打包一组依赖包,命名成一个规范的名称
  2. 自动注入SPI扩展代码
关于第一条,虽然jar包中并没有pom文件,但并不影响maven自动从网络或本地仓库中查找spring-boot-starter-web-{version}.pom文件,并导入相关依赖包。
第二条,实际上插件并非没有实现代码,而是被打到了spring-boot-autoconfigure.jar这个jar包中了,我们引入spring boot的依赖时,会自动加载该jar包。我们找到这个包,打开来看看里边的内容:
我们可以看到真正的spring-boot-starter-web的代码实现了。
了解了springboot官方插件实现机制,我们不禁要问,为什么springboot官方插件要这么去实现呢?
其实,小编并没有找到标准答案,不过小编觉得,这样做不外乎规范化,将官方插件实现代码统一集中存放。反过来,读者也可以想一想,这样实现有没有问题呢?
答案是有可能,试想一下,我们不引入spring-boot-starter-web这个插件,但是引入了这个插件需要的所有jar包,会怎么样呢?不错,会实现跟引入这个插件依赖一样的效果。实际编码过程中,很多时候,我们虽然没有依赖某个插件,但是却能实现和引入这个插件一样的效果,可能就是因为此原因导致的。
(0)

相关推荐