[Spring 企业应用加速小技巧]将bean扫描提前到编译器,加快应用启动速度

简介: [Spring 企业应用加速小技巧]将bean扫描提前到编译器,加快应用启动速度

@Indexed

Spring 在进行组件扫描时,会遍历项目中依赖的所有 Jar 包中类路径下所有的文件,找到被 @Component 及其衍生注解标记的类,然后把它们组装成 BeanDefinition 添加到 Spring 容器中。

如果扫描的返回过大,势必会大大地影响项目启动速度。

为了优化扫描速度,引入以下依赖,Spring 将扫描过程提前到编译期:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-indexer</artifactId>
    <optional>true</optional>
</dependency>
package com.example.index;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.stereotype.Component;
import java.util.Arrays;
public class IndexApplication {
    @Component
    static class Bean1 {}
    @Component
    static class Bean2 {}
    @Component
    static class Bean3 {}
    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(factory);
        String packageName = IndexApplication.class.getPackageName();
        System.out.println(">>>>> packageName="+packageName);
        int scan = scanner.scan(packageName);
        System.out.println(">>>>> scan="+scan);
        Arrays.stream(factory.getBeanDefinitionNames()).forEach(System.out::println);
    }
}

运行结果

>>>>> packageName=com.example.index
>>>>> scan=8
indexApplication.Bean1
indexApplication.Bean2
indexApplication.Bean3
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory

运行完了之后,会生成一份 target/classes/META-INF/spring.components文件,里面的内容是($ 表示内部类 )

com.example.index.IndexApplication$Bean1=org.springframework.stereotype.Component
com.example.index.IndexApplication$Bean2=org.springframework.stereotype.Component
com.example.index.IndexApplication$Bean3=org.springframework.stereotype.Component

如果把这个文件的某个 bean删除之后,那么这个 bean就不会被注册到 ioc容器。

它是在引入 spring-context-indexer 依赖后,在编译期根据类是否被 @Indexed 注解标记,生成 spring.components 文件及内容。

到目前为止,虽然都没显式使用 @Indexed 注解,但它包含在 @Component 注解中:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
  /**
   * The value may indicate a suggestion for a logical component name,
   * to be turned into a Spring bean name in case of an autodetected component.
   * @return the suggested component name, if any (or empty String otherwise)
   */
  String value() default "";
}

导入 spring-context-indexer 依赖后,在编译期根据 @Indexed 生成 META-INF/spring.components 文件。

Spring 在扫描组件时,如果发现 META-INF/spring.components 文件存在,以它为准加载 BeanDefinition,反之遍历包含 Jar 包类路径下所有 class 信息。

相关文章
|
18天前
|
XML 安全 Java
|
2天前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
25 3
|
18天前
|
XML Java 数据格式
Spring Core核心类库的功能与应用实践分析
【12月更文挑战第1天】大家好,今天我们来聊聊Spring Core这个强大的核心类库。Spring Core作为Spring框架的基础,提供了控制反转(IOC)和依赖注入(DI)等核心功能,以及企业级功能,如JNDI和定时任务等。通过本文,我们将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring Core,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
42 14
|
16天前
|
XML 前端开发 安全
Spring MVC:深入理解与应用实践
Spring MVC是Spring框架提供的一个用于构建Web应用程序的Model-View-Controller(MVC)实现。它通过分离业务逻辑、数据、显示来组织代码,使得Web应用程序的开发变得更加简洁和高效。本文将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring MVC,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
45 2
|
1月前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
16天前
|
安全 Java 开发者
Spring容器中的bean是线程安全的吗?
Spring容器中的bean默认为单例模式,多线程环境下若操作共享成员变量,易引发线程安全问题。Spring未对单例bean做线程安全处理,需开发者自行解决。通常,Spring bean(如Controller、Service、Dao)无状态变化,故多为线程安全。若涉及线程安全问题,可通过编码或设置bean作用域为prototype解决。
27 1
|
24天前
|
JSON 安全 算法
Spring Boot 应用如何实现 JWT 认证?
Spring Boot 应用如何实现 JWT 认证?
54 8
|
1月前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
22天前
|
消息中间件 Java Kafka
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
34 1
|
1月前
|
Java Docker 微服务
利用Docker容器化部署Spring Boot应用
利用Docker容器化部署Spring Boot应用
47 0