第四十四讲-@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 文件, 扫描时

  1. 如果发现 META-INF/spring.components 存在, 以它为准加载 bean definition
  2. 否则, 会遍历包下所有 class 资源 (包括 jar 内的)
posted @   LilyFlower  阅读(13)  评论(0编辑  收藏  举报
编辑推荐:
· .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语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示