Spring Cloud Gateway启动失败:routerFunctionMapping Bean及CGLIB子类生成异常
问题根源
Spring Boot DevTools采用双类加载器机制:RestartClassLoader负责加载应用代码,LaunchedURLClassLoader加载基础依赖。CGLIB生成的子类(由RestartClassLoader加载)尝试访问GatewayMvcPropertiesBeanDefinitionRegistrar$RouterFunctionHolder父类时,若父类被另一类加载器加载,JVM会判定为跨类空间访问,触发IllegalAccessError,进而导致BeanCreationException。
解决步骤
1. 排除DevTools的冲突依赖
在构建文件中给DevTools排除spring-core和cglib依赖,避免类加载器冲突:
Maven(pom.xml):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </exclusion> <exclusion> <groupId>cglib</groupId> <artifactId>cglib</artifactId> </exclusion> </exclusions> </dependency>
Gradle(build.gradle):
developmentOnly("org.springframework.boot:spring-boot-devtools") { exclude group: 'org.springframework', module: 'spring-core' exclude group: 'cglib', module: 'cglib' }
2. 统一CGLIB版本
显式声明与Spring Cloud Gateway匹配的CGLIB版本,消除版本差异:
Maven:
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> <!-- 需与Spring Cloud Gateway依赖版本一致 --> </dependency>
Gradle:
implementation 'cglib:cglib:3.3.0'
3. 让DevTools忽略网关核心类
在src/main/resources/META-INF/spring-devtools.properties中添加配置,禁止DevTools对网关配置类进行重启类加载:
restart.exclude.gateway=org.springframework.cloud.gateway.server.mvc.config.**
4. 临时禁用DevTools(应急方案)
若上述方法无效,先移除DevTools依赖确认问题:
Maven:
<!-- 暂时注释DevTools依赖 --> <!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> -->
Gradle:
// 暂时移除DevTools依赖 // developmentOnly("org.springframework.boot:spring-boot-devtools")
5. 调整JVM启动参数
添加-Dspring.devtools.restart.enabled=false参数启动应用,直接禁用DevTools的重启功能,规避类加载器冲突。
验证
执行mvn clean install或gradle clean build后重启应用,检查是否仍抛出相关异常。
内容的提问来源于stack exchange,提问作者Shubham Patil

