目录
前言
在Spring的常用注解,可参考如下:
在 Java 中,
@Indexed
注解通常用于标记类或元素可以被索引(例如在 Spring 框架或 JPA 中用于加速检索)。
如下图所示:
最佳实践
Spring 项目:
若组件数量多(>100),使用
spring-context-indexer
提升启动速度。避免滥用,索引文件需随代码重新生成(适合静态不变的类)。
数据库优化:
在 JPA 中为查询频繁的字段(如
email
、username
)添加@Index
。
全文检索:
结合 Elasticsearch 的
@Field
配置分词器和索引类型。
1. Spring 框架中的 @Indexed
1.1、问题:
Spring 启动时要扫描所有
@Component
、@Service
等注解的类,如果项目有 1000 个类,每次启动都要全盘扫描,速度很慢。应用中使用
<context:component-scan />
或@ComponentScan
扫描的package
包含的类越来越多的时候,Spring启动时模式注解解析时间就会变得越长。
解决:
给需要被扫描的类加
@Indexed
,编译时会生成一个 索引列表文件(META-INF/spring.components
)。
下次启动时,Spring 直接读这个列表,不用再扫描,启动速度大幅提升。
1.2、定义
@Indexed是Spring5.0引入的新特性,用于优化大量@ComponentScan扫描时的性能。
它通过在编译时生成META-INF/spring.components文件,存储模式注解信息,启动时读取此文件而非实际扫描,从而加快应用启动时间。
注意:只有使用了@Indexed的jar包中的模式注解才会被识别。
1.3、使用场景
大型项目中包含大量 @Component
、@Service
等注解的类时,通过预编译生成索引优化启动性能。
示例:
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Indexed;
@Indexed // 标记该类可被索引
@Component
public class UserService {
// 类实现...
}
生效条件:
需在项目中添加依赖(Spring 5.0+):
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
<version>5.1.12.RELEASE</version>
<optional>true</optional>
</dependency>
</dependencies>
编译后会在 target/classes/META-INF
下生成 spring.components
文件。
2. JPA/Hibernate 中的 @Index
2.1、作用:
为数据库表的列或字段创建索引,提高查询性能(非
@Indexed
,但功能相关)。
2.2、示例代码:
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.Table;
@Entity
@Table(name = "users", indexes = {
@Index(columnList = "email", name = "idx_user_email") // 为email字段创建索引
})
public class User {
private String email;
// 其他字段...
}
3. 其他场景的索引注解
Lucene/Elasticsearch(全文检索)
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
@Document(indexName = "products")
public class Product {
@Field(type = FieldType.Keyword)
private String id;
@Field(type = FieldType.Text, analyzer = "ik_max_word") // 中文分词
private String name;
}
4. 自定义 @Indexed
注解
在Spring5版本后,可以看到@Component注解的源码包含了@Indexed;
如果需要自定义索引逻辑,可以定义自己的注解:
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Indexed {
String value() default ""; // 可指定索引名称
}
参考文章: