关于Spring5新增的Indexed注解
前言
如果我们应用中使用@ComponentScan注解扫描的package包含的类很多的时候,Spring解析耗时就会很多,相应的应用启动时间也就更长,Spring 5.0 引入了一个新的注解@Indexed ,它可以为Spring的模式注解添加索引,以提升应用启动性能。
使用
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
<version>5.3.18</version>
</dependency>
注意,现在Spring中的Component注解上已经默认添加了Indexed注解
项目编译之后,会自动生成一个 META-INT/spring.components 文件,Spring 处理 ComponentScan 注解扫描时,会先读取此文件,而不会去实际的扫描 package,这样就加快了应用启动速度。
内容为
com.imooc.messagequeue.Application=org.springframework.stereotype.Component
com.imooc.messagequeue.config.RabbitMqConfig=org.springframework.stereotype.Component
com.imooc.messagequeue.config.WebConfig=org.springframework.stereotype.Component
com.imooc.messagequeue.service.RabbitMqOrderPayConsumer=org.springframework.stereotype.Component
com.imooc.messagequeue.service.RabbitMqSender=org.springframework.stereotype.Component
com.imooc.messagequeue.web.TestController=org.springframework.stereotype.Component
原理分析
- CandidateComponentsIndexer 是一个注解处理器,类似于lombok中的注解处理器,在编译时解析所有 class 文件,找到其中包含 Indexed 注解的类,并最终写入到 spring.components 文件中。
- CandidateComponentsIndexLoader 在应用启动时,会读取 spring.components 文件,封装为 CandidateComponentsIndex 对象,如果我们配置了 启动参数 -Dspring.index.ignore=true,就不会读取此文件。
- ClassPathScanningCandidateComponentProvider 在处理 ComponentScan 注解时,如果发现 CandidateComponentsIndex 对象存在(表示成功读取了 spring.components 文件),就会直接获取到扫描类信息,而不会再去实际扫描 package。
总结
此功能就是将原本在运行期的扫描工作提前到了编译期,以此来加快应用启动速度。
注意:spring.index.ignore=true 这个配置必须是启动参数的配置,而不是 application.yml 中配置,不然读取不到。