第四十四讲-@Indexed的原理
第四十四讲-@Indexed的原理
本讲我们讲一下@Indexed注解的原理。
我们都知道,Spring中组件扫描的效率是非常低的,因为它要去遍历项目中所有的jar包,然后classes目录下所有的类文件,一个类一个类去进行分析,看看这些类上有没有标注@Component及其它的派生注解,如果有的话,它会将该类变成BeanDefinition,并加入到容器当中。如果是在Spring启动的过程中扫描的范围特别的大,那势必会影响到Spring的启动速度,所以,Spring在5.0中它做了一个优化,能够解决这个问题,它是怎么做的呢?如下面的例子:
@Component
public class Bean1 {
}
@Component
public class Bean2 {
}
@Component
public class Bean3 {
}
/*
做这个试验前, 先在 target/classes 创建 META-INF/spring.components, 内容为
com.itheima.a44.Bean1=org.springframework.stereotype.Component
com.itheima.a44.Bean2=org.springframework.stereotype.Component
做完实现建议删除, 避免影响其它组件扫描的结果
真实项目中, 这个步骤可以自动完成, 加入以下依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
<optional>true</optional>
</dependency>
*/
public class A44 {
public static void main(String[] args) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 组件扫描的核心类
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(beanFactory);
scanner.scan(A44.class.getPackageName());
for (String name : beanFactory.getBeanDefinitionNames()) {
System.out.println(name);
}
}
}
记得加下面的依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
<optional>true</optional>
</dependency>
上面依赖的作用是是在编译阶段去找这些类上有没有加@Indexed的注解,如果有,就把这个Bean记录下来加入到一个叫spring.components
文件中。
需要注意的是@Component注解上间接加了@Indexed注解:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
String value() default "";
}
这就是Spring5.0 新增了@Indexed注解加速了组件的扫描,其实加速的原理就是把扫描的时间提前了,不是在Spring程序运行的时候做扫描工作,而是在编译的时候就把组件扫描这件事做好了,把结果存入到文件中,也就是spring.components
文件中,这样可以直接从文件中读取结果就可以了,而不是在运行时再扫描jar包读取哪些类上加了@Component注解。
com.cherry.a44.Bean1=org.springframework.stereotype.Component
com.cherry.a44.Bean2 org.springframework.stereotype.Component
我们总结一下:
学到了什么
a. @Indexed 的原理, 在编译时就根据 @Indexed 生成 META-INF/spring.components 文件, 扫描时
- 如果发现 META-INF/spring.components 存在, 以它为准加载 bean definition
- 否则, 会遍历包下所有 class 资源 (包括 jar 内的)
分类:
Spring 高级49讲
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构