核心问题是混淆后注解未保留在字节码中,导致反射查不到;必须用-keepattributes annotation,signature,localvariabletable,localvariabletypetable保留元数据,并精准保留spring注解、配置类、自动配置类及spi实现类名称。

核心问题不是“反射找不到注解”,而是注解在混淆后根本没被保留在字节码里——运行时连注解的影子都看不到,反射自然查无此物。这在 Spring Boot、Dubbo、MyBatis 等重度依赖注解的框架中尤为致命。
必须保留注解的运行时元数据
ProGuard 默认会剥离所有注解(包括 @Retention(RUNTIME) 的),导致 clazz.getAnnotation(...) 永远返回 null。这不是配置粒度不够,而是基础属性缺失。
- -keepattributes *Annotation*,Signature,LocalVariableTable,LocalVariableTypeTable —— 放在规则文件最顶部,缺一不可
- 仅写
-keepattributes RuntimeVisibleAnnotations不够,Spring 5+ 和部分现代框架会读取RuntimeInvisibleAnnotations或其他扩展属性 -
Signature防止泛型擦除影响 @Autowired 泛型注入;LocalVariableTable和LocalVariableTypeTable是调试和某些 AOP 场景必需
精准锁定 Spring 注解及其使用位置
不能只保留注解类本身,还要确保它们“附着”的地方不被混淆或移除——方法名、字段名、类名一旦改掉,Spring 就无法按约定匹配。
- 保留所有 Spring 核心注解声明的方法:
-keepclassmembers class * {<br> @org.springframework.context.annotation.Bean *;<br> @org.springframework.beans.factory.annotation.Autowired *;<br> @org.springframework.beans.factory.annotation.Value *;<br> @org.springframework.web.bind.annotation.** *;<br> @org.springframework.stereotype.** *;<br>} - 对配置类额外加固:
-keep @org.springframework.context.annotation.Configuration class *<br>-keepclassmembers @org.springframework.context.annotation.Configuration class * { *; } - 避免用模糊通配如
@interface *,容易漏掉嵌套注解或第三方扩展注解(如@Validated)
保障自动配置与 SPI 机制不被破坏
Spring Boot 的 META-INF/spring.factories 文件靠全限定类名加载自动配置类。一旦类名被混淆,整个 autoconfigure 链就断了。
- 显式保留所有自动配置类:
-keep class org.springframework.boot.autoconfigure.** { *; } - 保留关键 SPI 接口实现类的原始名称:
-keepnames class * implements org.springframework.boot.autoconfigure.AutoConfigurationImportSelector<br>-keepnames class * implements org.springframework.boot.autoconfigure.EnableAutoConfiguration
- 检查
spring.factories中列出的每个类是否都在 mapping.txt 中有原始名称映射,否则补-keepnames
验证注解是否真正存活
别只信日志或启动成功——要实测注解是否还在运行时可见。
- 写一个启动后执行的简单校验逻辑:
System.out.println(MyService.class.getAnnotation(Service.class) != null); - 用
javap -v反编译混淆后的 class,搜索RuntimeVisibleAnnotations属性是否存在 - 打开
mapping.txt,确认带注解的类/方法未被重命名(如com.example.MyController仍为原名,而非a.b.c)










