You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Boot DevTools中排除指定Java包重启类加载器

Fixing Slow Spring Boot DevTools Restarts: Excluding Specific Packages from Restart ClassLoader

Hey, I totally get where you’re coming from—dealing with glacial DevTools restarts thanks to heavy database and cache initialization is such a pain, especially when excluding entire modules only cuts the time a little. Let’s break down why your current config isn’t working and walk through actionable fixes.

Why Your Existing Config Failed

The key thing to know about DevTools’ restart mechanism is that it works at the directory/jar level, not individual package paths. When you tried restart.exclude.config=/modules/mainmodule/target/classes/com/company/app/configs/, DevTools didn’t recognize it because it only scans entire resource roots (like the full target/classes folder) to decide what goes into the restartable classloader. It can’t pick out subpackages directly from that root.


1. Flip the Approach: Include Only What You Need to Restart

Instead of trying to exclude specific packages, reverse the logic: explicitly include only the 2-3 packages you actually modify, and exclude the rest of the classes directory. This way, the heavy initialization code stays in the base classloader (which doesn’t restart).

Add this to your application-dev.properties:

# Include only the packages you actively work on (comma-separate multiple paths)
spring.devtools.restart.include.active-code=/modules/mainmodule/target/classes/com/company/app/service/**,/modules/mainmodule/target/classes/com/company/app/controller/**
# Exclude the entire classes directory so unincluded code stays in the base classloader
spring.devtools.restart.exclude.base-code=/modules/mainmodule/target/classes/**

Pro tip: Use Ant-style patterns (** for any subdirectory) to make sure you cover all nested classes in your target packages.

2. Skip Heavy Initialization in Dev Mode (The Fastest Win)

Since your main bottleneck is DB/cache setup, the most impactful fix is to lighten that load when using DevTools:

  • Use an embedded database: Swap your production DB for H2 in dev mode—initialization is almost instant compared to connecting to a remote or full-scale DB.
  • Switch to in-memory caching: Replace distributed caches like Redis with a lightweight in-memory option (Caffeine or Guava Cache) for dev.
  • Conditionally disable heavy beans: Use profiles or properties to skip production-grade initialization in dev:
    @Configuration
    @Profile("!dev") // Only load this in non-dev environments
    public class HeavyDatabaseConfig {
        // Your slow DB connection pool, migration logic, etc.
    }
    
    Or use a property toggle:
    @Bean
    public CacheManager cacheManager(@Value("${dev.use-lightweight-cache:true}") boolean useLightweight) {
        if (useLightweight) {
            return new CaffeineCacheManager(); // Fast in-memory cache
        }
        // Production cache setup (only runs when not in dev)
        return new RedisCacheManager(redisConnectionFactory());
    }
    

3. Package Heavy Code into a Separate JAR

If you can’t split your module, compile the classes with heavy initialization into a standalone JAR, drop it into your project’s lib folder, then exclude that JAR from restart:

spring.devtools.restart.exclude.heavy-lib=/lib/initialization-heavy.jar

This JAR will load into the base classloader, so it won’t be reloaded during restarts.


Verify It’s Working

To confirm your config classes are now in the base classloader (not the restartable one), add a quick endpoint to check:

@RestController
public class ClassLoaderChecker {
    @GetMapping("/class-loader-info")
    public String checkLoaders() {
        String controllerLoader = this.getClass().getClassLoader().getClass().getName();
        String configLoader = YourHeavyConfigClass.class.getClassLoader().getClass().getName();
        return String.format("Controller ClassLoader: %s%nConfig ClassLoader: %s", controllerLoader, configLoader);
    }
}

If the config class uses sun.misc.Launcher$AppClassLoader (or similar) instead of RestartClassLoader, you’re good to go!


内容的提问来源于stack exchange,提问作者user2529617

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:06:28