升级spring-data-mongodb-encrypt触发NoSuchMethodError报错解决方案咨询
问题根因
你遇到的NoSuchMethodError是版本不兼容直接导致的:Spring Boot 1.4.2内置的spring-data-mongodb版本为1.9.x,该版本的org.springframework.data.mongodb.core.mapping.event.AfterLoadEvent类仅提供getDBObject()方法,返回DBObject类型对象;而spring-data-mongodb-encrypt 2.3.1依赖spring-data-mongodb 2.x版本,该版本才新增了getDocument()方法,返回org.bson.Document类型对象,二者API不匹配直接触发启动报错。
不升级Spring Boot的解决方案
方案1:降级
spring-data-mongodb-encrypt到兼容1.x版本
如果没有必须使用2.3.1版本新特性的需求,直接退回到你之前正常运行的1.3.0版本即可,这是成本最低的解决方案。方案2:自定义适配版本的加密事件监听器
如果必须使用2.3.1版本的功能,你可以手动适配API差异,步骤如下:- 排除依赖包的自动配置:在启动类注解中排除加密包的自动配置类,避免框架自动注册原生监听器:
@SpringBootApplication(exclude = com.bol.secure.EncryptionAutoConfiguration.class)- 自定义加密事件监听器:继承原有
CachedEncryptionEventListener,重写涉及事件API的方法,适配1.x版本的getDBObject()方法:
public class CompatibleEncryptionEventListener extends CachedEncryptionEventListener { // 保留原有构造方法,注入加密配置、缓存等依赖 public CompatibleEncryptionEventListener(EncryptionService encryptionService, Cache cache) { super(encryptionService, cache); } @Override public void onAfterLoad(AfterLoadEvent<Object> event) { // 适配1.x API,先获取DBObject再转换为Document DBObject dbObject = event.getDBObject(); Document document = new Document((BasicDBObject) dbObject); // 复用父类解密逻辑,若父类方法直接调用event.getDocument(),可直接复制父类对应逻辑替换获取document的部分即可 } // 同理重写其他调用了事件getDocument()的方法,比如onBeforeSave等,把getDocument()调用替换为1.x API的转换结果 }- 将自定义的监听器注册为Spring Bean,替代原生实现即可正常运行。
方案3:单独升级
spring-data-mongodb到2.x兼容版本
该方案需要你自行测试spring-data-mongodb 2.x和Spring Boot 1.4.2的兼容性,需要处理可能出现的其他依赖冲突、API变更问题,成本高于前两种方案,不优先推荐。
内容的提问来源于stack exchange,提问作者Ann
相关产品推荐
相关产品推荐

