跳转至

Spring 启动与并发性能优化


启动性能优化

1. 懒加载策略

配置懒加载 Bean

@Configuration
public class LazyLoadingConfig {

    // 大型服务使用懒加载
    @Bean
    @Lazy
    public HeavyService heavyService() {
        return new HeavyService();
    }

    // 只在特定环境下加载的Bean
    @Bean
    @Profile("!test")
    public ProductionService productionService() {
        return new ProductionService();
    }

    // 条件加载的Bean
    @Bean
    @ConditionalOnProperty(name = "feature.advanced", havingValue = "true")
    public AdvancedFeatureService advancedFeatureService() {
        return new AdvancedFeatureService();
    }
}

// 懒加载服务示例
@Service
@Lazy
public class HeavyService {

    private final List<BigObject> cache = new ArrayList<>();

    @PostConstruct
    public void init() {
        // 初始化耗时操作
        logger.info("HeavyService 初始化开始...");

        // 模拟耗时初始化
        for (int i = 0; i < 10000; i++) {
            cache.add(new BigObject("object_" + i));
        }

        logger.info("HeavyService 初始化完成");
    }

    public void doSomething() {
        // 业务逻辑
    }
}

组件扫描优化

@Configuration
@ComponentScan(
    basePackages = {
        "com.example.core",
        "com.example.service"
    },
    excludeFilters = @ComponentScan.Filter(
        type = FilterType.REGEX, 
        pattern = "com\.example\.service\.internal\..*"
    )
)
public class OptimizedComponentScanConfig {

    // 手动注册需要排除内部包但需要使用的Bean
    @Bean
    public InternalService internalService() {
        return new InternalService();
    }
}

// 启动类优化
@SpringBootApplication(
    scanBasePackages = {
        "com.example.controller",
        "com.example.service",
        "com.example.repository"
    },
    exclude = {
        DataSourceAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class
    }
)
public class OptimizedApplication {

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(OptimizedApplication.class);

        // 优化启动配置
        app.setBannerMode(Banner.Mode.OFF);
        app.setLogStartupInfo(false);
        app.setLazyInitialization(true); // 启用懒加载

        app.run(args);
    }
}

2. 类路径优化

减少不必要的依赖

<!-- pom.xml 依赖优化 -->
<dependencies>
    <!-- 核心Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <!-- 排除不需要的组件 -->
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <!-- 使用更轻量的Web服务器 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-undertow</artifactId>
    </dependency>

    <!-- 按需引入Jackson -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.15.2</version>
    </dependency>

    <!-- 使用provided范围的依赖 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <scope>provided</scope>
    </dependency>
</dependencies>

3. AOT 编译优化

AOT(Ahead-of-Time)编译可以将 Spring 应用在构建时预处理,大幅减少启动时间。

Spring AOT 配置(Spring Boot 3.x)

// 1. Maven 配置
// pom.xml
// <plugin>
//     <groupId>org.springframework.boot</groupId>
//     <artifactId>spring-boot-maven-plugin</artifactId>
//     <configuration>
//         <image>
//             <builder>paketobuildpacks/builder:tiny</builder>
//         </image>
//     </configuration>
// </plugin>
// <plugin>
//     <groupId>org.graalvm.buildtools</groupId>
//     <artifactId>native-maven-plugin</artifactId>
// </plugin>

// 2. AOT 运行时提示(Runtime Hints)
@Configuration
@ImportRuntimeHints(MyRuntimeHints.class)
public class AotConfig {
    // AOT 相关配置
}

public class MyRuntimeHints implements RuntimeHintsRegistrar {

    @Override
    public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
        // 注册反射提示(AOT 编译时需要)
        hints.reflection()
            .registerType(User.class, MemberCategory.values())
            .registerType(Order.class, MemberCategory.values());

        // 注册资源提示
        hints.resources()
            .registerPattern("config/*.properties")
            .registerPattern("templates/*.html");

        // 注册序列化提示
        hints.serialization()
            .registerType(User.class)
            .registerType(Order.class);

        // 注册代理提示
        hints.proxies()
            .registerJdkProxy(UserService.class);
    }
}

// 3. 条件化 Bean 注册(AOT 友好)
@Configuration
public class AotFriendlyConfig {

    // 避免在 AOT 中使用动态 Bean 注册
    // 使用 @Bean 替代 BeanFactoryPostProcessor 动态注册
    @Bean
    @ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
    public FeatureService featureService() {
        return new FeatureService();
    }
}

GraalVM Native Image 构建

# 构建 Native Image
mvn -Pnative native:compile

# 运行 Native Image(启动时间通常 < 100ms)
./target/my-application

# Docker 构建 Native Image
mvn -Pnative spring-boot:build-image

AOT/Native Image 注意事项: - 反射、动态代理、JNI 需要提前注册 Runtime Hints - 部分第三方库可能不兼容 Native Image - 构建时间较长,建议 CI/CD 环境构建 - 启动时间可从秒级降至毫秒级,内存占用减少 50%+

类路径扫描优化

// 自定义类路径扫描器
@Component
public class OptimizedClassPathScanner {

    public Set<Class<?>> scanPackages(String... basePackages) {
        ClassPathScanningCandidateComponentProvider scanner = 
            new ClassPathScanningCandidateComponentProvider(false);

        // 添加类型过滤器
        scanner.addIncludeFilter(new AnnotationTypeFilter(Service.class));
        scanner.addIncludeFilter(new AnnotationTypeFilter(Component.class));
        scanner.addIncludeFilter(new AnnotationTypeFilter(Repository.class));

        Set<Class<?>> classes = new HashSet<>();
        for (String basePackage : basePackages) {
            Set<BeanDefinition> candidates = scanner.findCandidateComponents(basePackage);
            for (BeanDefinition candidate : candidates) {
                try {
                    classes.add(Class.forName(candidate.getBeanClassName()));
                } catch (ClassNotFoundException e) {
                    logger.warn("无法加载类: {}", candidate.getBeanClassName());
                }
            }
        }

        return classes;
    }
}

并发性能优化

1. 线程池优化配置

Spring 异步线程池配置

@Configuration
@EnableAsync
public class AsyncThreadPoolConfig {

    // CPU 密集型任务线程池
    @Bean("cpuIntensiveExecutor")
    public Executor cpuIntensiveExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(Runtime.getRuntime().availableProcessors());
        executor.setMaxPoolSize(Runtime.getRuntime().availableProcessors() * 2);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("cpu-intensive-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(60);
        executor.initialize();
        return executor;
    }

    // I/O 密集型任务线程池
    @Bean("ioIntensiveExecutor")
    public Executor ioIntensiveExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(20);
        executor.setMaxPoolSize(100);
        executor.setQueueCapacity(1000);
        executor.setThreadNamePrefix("io-intensive-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(60);
        executor.initialize();
        return executor;
    }

    // 定时任务线程池
    @Bean("scheduledExecutor")
    public Executor scheduledExecutor() {
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
        return new DelegatingExecutor(executor);
    }

    // 虚拟线程执行器(Java 21+)
    @Bean("virtualThreadExecutor")
    @ConditionalOnJava(range = ConditionalOnJava.Range.EQUAL_OR_NEWER, value = JavaVersion.SEVENTEEN)
    public Executor virtualThreadExecutor() {
        return Executors.newVirtualThreadPerTaskExecutor();
    }
}

// 使用不同线程池的异步服务
@Service
public class OptimizedAsyncService {

    // CPU 密集型任务
    @Async("cpuIntensiveExecutor")
    public CompletableFuture<BigDecimal> calculateComplexData(ComplexData data) {
        // 复杂计算逻辑
        return CompletableFuture.completedFuture(performCalculation(data));
    }

    // I/O 密集型任务
    @Async("ioIntensiveExecutor")
    public CompletableFuture<String> processFileUpload(MultipartFile file) {
        // 文件处理逻辑
        return CompletableFuture.completedFuture(processFile(file));
    }

    // 虚拟线程任务(高并发场景)
    @Async("virtualThreadExecutor")
    public CompletableFuture<Void> handleHighConcurrencyRequest(RequestData data) {
        // 高并发处理逻辑
        return CompletableFuture.completedFuture(null);
    }

    private BigDecimal performCalculation(ComplexData data) {
        // 计算逻辑
        return BigDecimal.ZERO;
    }

    private String processFile(MultipartFile file) {
        // 文件处理逻辑
        return "processed";
    }
}

连接池优化

@Configuration
public class ConnectionPoolConfig {

    // HikariCP 连接池配置(推荐)
    @Bean
    @ConfigurationProperties("spring.datasource.hikari")
    public HikariDataSource dataSource() {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setMaximumPoolSize(20);
        dataSource.setMinimumIdle(5);
        dataSource.setIdleTimeout(300000);
        dataSource.setConnectionTimeout(20000);
        dataSource.setMaxLifetime(1200000);
        dataSource.setLeakDetectionThreshold(60000);
        return dataSource;
    }

    // Redis 连接池配置
    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("localhost", 6379);

        LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
            .commandTimeout(Duration.ofSeconds(2))
            .shutdownTimeout(Duration.ofSeconds(2))
            .clientResources(ClientResources.builder()
                .ioThreadPoolSize(4)
                .computationThreadPoolSize(4)
                .build())
            .build();

        return new LettuceConnectionFactory(config, clientConfig);
    }

    // HTTP 客户端连接池
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplateBuilder()
            .setConnectTimeout(Duration.ofSeconds(5))
            .setReadTimeout(Duration.ofSeconds(10))
            .requestFactory(() -> {
                HttpComponentsClientHttpRequestFactory factory = 
                    new HttpComponentsClientHttpRequestFactory();
                factory.setConnectionRequestTimeout(5000);
                factory.setConnectTimeout(5000);
                factory.setReadTimeout(10000);
                return factory;
            })
            .build();
    }
}

2. 响应式编程优化

WebFlux 性能优化

@Configuration
public class WebFluxConfig {

    @Bean
    public WebFluxConfigurer webFluxConfigurer() {
        return new WebFluxConfigurer() {
            @Override
            public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
                // 配置编解码器
                configurer.defaultCodecs().maxInMemorySize(10 * 1024 * 1024); // 10MB
            }

            @Override
            public void configurePathMatching(PathMatchConfigurer configurer) {
                // 优化路径匹配
                configurer.setUseTrailingSlashMatch(false);
            }
        };
    }

    @Bean
    public RouterFunction<ServerResponse> routerFunction() {
        return RouterFunctions.route()
            .GET("/api/users", this::getAllUsers)
            .GET("/api/users/{id}", this::getUserById)
            .POST("/api/users", this::createUser)
            .build();
    }

    private Mono<ServerResponse> getAllUsers(ServerRequest request) {
        return ServerResponse.ok()
            .contentType(MediaType.APPLICATION_JSON)
            .body(userService.findAllUsers(), User.class);
    }

    private Mono<ServerResponse> getUserById(ServerRequest request) {
        String id = request.pathVariable("id");
        return userService.findUserById(id)
            .flatMap(user -> ServerResponse.ok().bodyValue(user))
            .switchIfEmpty(ServerResponse.notFound().build());
    }

    private Mono<ServerResponse> createUser(ServerRequest request) {
        return request.bodyToMono(User.class)
            .flatMap(userService::createUser)
            .flatMap(user -> ServerResponse.created(URI.create("/api/users/" + user.getId())).bodyValue(user));
    }
}

// 响应式数据访问优化
@Repository
public class ReactiveUserRepository {

    private final R2dbcEntityTemplate entityTemplate;

    public ReactiveUserRepository(R2dbcEntityTemplate entityTemplate) {
        this.entityTemplate = entityTemplate;
    }

    // 批量插入优化
    public Flux<User> saveAllOptimized(Flux<User> users) {
        return users.buffer(100) // 每100条一批
            .flatMap(batch -> entityTemplate.insert(User.class).all(Flux.fromIterable(batch)));
    }

    // 分页查询优化
    public Flux<User> findAllWithPaging(int page, int size) {
        return entityTemplate.select(User.class)
            .matching(Query.empty().limit(size).offset(page * size))
            .all();
    }
}