我正在使用 ProGuard 进行 spring-boot 应用程序混淆。它工作正常,生成的 jar 已构建并且运行良好,没有任何问题。
为了实现这一目标,我进行了一些调整:
自定义 beanNameGenerator
public static void main(String[] args) { new SpringApplicationBuilder(MainApp.class) .beanNameGenerator((beanDefinition, beanDefinitionRegistry) -> beanDefinition.getBeanClassName()) .run(args); }
- 保留 Autowired、限定符、Bean、值注释成员,
- 保留主要方法
- keepattributes 与 Exceptions、InnerClasses、Signature、Deprecated、SourceFile、LineNumberTable、Annotation、EnclosureMethod 切换
- dontshrink、dontoptimize、useuniqueclassmembernames、adaptclassstrings、dontusemixedcaseclassnames 选项
但是,集成测试(@SpringBootTest)因错误而中断(在没有 proguard 的情况下构建时它们运行良好):
java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test.
包含主入口类(@SpringBootTest(classes=MainApp.class))后:
2019-09-11 19:00:13,178 [main] ERROR org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@6b04acb2] to prepare te
st instance [com.xxx.xxx.it.ExternalIT@258274cb]
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125) ~[spring-test-5.1.7.RELEASE.jar:5.1.7.RELEASE]
...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.xxx.xxx.a.a.b' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
等等。
除了创建新的配置文件来执行测试而不进行混淆之外,还有什么方法可以使其工作吗?
请您参考如下方法:
preservation of Autowired, Qualifier, Bean, Value annotation members,
你在这里做了正确的事情,你需要保留所有属性
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
但是这不是问题的原因,Spring 会按类型进行 Autowiring ,根据我的经验,混淆后此类问题是由于找不到类型的 bean 造成的。
您需要调整您的代码,使用名称类似于的注释
@Component("yourComponentName")
而不是
@Component
与bean和Service以及其他注释相同
无论你在哪里使用,都可以使用@Qualifier("nameofbeanorService")
由于您保留了注释属性,您的应用程序将顺利运行。
谢谢