@Indexed注解的作用
一.为什么需要 @Indexed?
在传统的 Spring 应用(特别是 Spring Boot)中,应用启动时,类路径扫描(Component Scanning)是一个重要的步骤。Spring 需要扫描 @Component
r
等注解的类,并将它们注册为 Bean。当你的应用拥有大量的 JAR 包和类时,全量的类路径扫描会变得非常耗时。@Indexed
就是为了解决这个问题而生的。
二.概述
@Indexed注解看起来比较陌生,但是@Component注解我们是比较熟悉的。该注解便存在其中,它是Spring 5.0 引入的一个组件索引功能的组成部分,用来标记扫描类的注解,在编译时生成一个静态的索引文件(META-INF/spring.components
),以便让Spring知道需要扫描哪些类以加快大型应用的启动速度。
三.代码测试
写一个测试类MyTest
package com.example.springdemo.demos.a12;import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** @author zhou* @version 1.0* @description TODO* @date 2025/8/28 22:08*/
public class MyTest {public static void main(String[] args) {DefaultListableBeanFactory factory = new DefaultListableBeanFactory();//Spring核心扫描容器ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(factory);scanner.scan(MyTest.class.getPackage().getName());for(String name : factory.getBeanDefinitionNames()){System.out.println(name);}}
}
该类主要是利用spring框架提供的扫描类扫描我的测试类下的包。并把类注入到容器类,下面三个类都加上了@Component注解。
Bean1
package com.example.springdemo.demos.a12;import org.springframework.stereotype.Component;/*** @author zhou* @version 1.0* @description TODO* @date 2025/8/28 22:13*/
@Component
public class Bean1 {
}
Bean2
package com.example.springdemo.demos.a12;import org.springframework.stereotype.Component;/*** @author zhou* @version 1.0* @description TODO* @date 2025/8/28 22:13*/
@Component
public class Bean2 {
}
Bean3
package com.example.springdemo.demos.a12;import org.springframework.stereotype.Component;/*** @author zhou* @version 1.0* @description TODO* @date 2025/8/28 22:14*/
@Component
public class Bean3 {
}
测试结果如下:
可以看到,容器里面只输出了Bean1。原因是我在target的META-INF目录下加了spring.components文件。在包扫描的时候首先会去看有没有这个文件,里面的键是标注了@Indexed注解的扫描的类,值是Component类的类路径。并不会走jar包和class扫描。
刚才的文件是我手动添加的,而在spring5.0版本之后,这个文件会自动生成,如果没有该文件Spring会遍历所有的Class文资源,如果我们手动修改了该类,则以我们修改的为准。这个功能需要加入下面的注解处理器依赖。(SpringBoot已经集成了,下面的是本项目中的版本,实际根据Spring的版本来)。
<dependency><groupId>org.springframework</groupId><artifactId>spring-context-indexer</artifactId><version>5.3.23</version><optional>true</optional> <!-- 推荐设置为 optional,防止传递到其他模块 --></dependency>
它只在编译时需要,不会打包到最终的运行时 JAR/WAR 中。<optional>true</optional>
确保这个依赖不会被传递到依赖你项目的其他模块。
添加依赖再次测试结果如下:
自动生成了spring.components文件,扫描了项目中所有带@Indexed注解的类写入进去。
也许你会发现我们并没有在类上加@Indexed注解,那它为什么去扫描了文件中的类,其实是因为@Component是一个派生注解,它上面有@Indexed注解。