背景
最近在团队内部写了一个简单的基于spring boot
的sdk,我这边使用的spring boot
版本为2.4.2
。然后在sdk稳定上线后其他项目也想使用,在使用中发现引入sdk后起不来。报错这里可以看到报错信息也很明显就是
AnnotationUtils.isCandidateClass()
方法不存在,而方法AnnotationUtils.isCandidateClass
又是我直接使用了 spring boot
的工具类
如果以sdk
这边的spring boot
版本来说是存在这个方法的,但是实际项目使用的spring boot
版本为2.1.3.RELEASE
,算是比较老的版本了。那么遇到这种版本不兼容问题如何处理呢
处理方式
直接copy方法
最简单的方式就是直接把这个方法统统copy一次,放到自己项目中,当做自己的工具类使用,这样就不用依赖spring boot
的版本了,因为原先开源框架的设计本身就应该不要过度依赖三方sdk,否则可能会有很多版本冲突问题,但是我这个框架本身就是基于spring boot
自动装配的,所以使用spring boot
中内置的一些方法也无可厚非.所以这种方式不够优雅
版本推断选择方法调用
通过两个版本的方法比对我们发现AnnotationUtils.isCandidateClass
方法在低版本的spring boot
中使用的!isSpringContainerClass
代替的
知道了替代方法我们的处理方式就简单了,低版本的spring boot
我直接调用!isSpringContainerClass(targetType)
方法即可。那么问题又变成了如何判断spring boot
版本问题
如果你对Spring Boot
条件注解ConditionalOnJava
熟悉的话就可以参考这种方式去实现ConditionalOnJava
需要判断当前jdk版本,而他的做法就是通过特定jdk版本有不同方法去判断jdk版本的
所以我们只需要判断当前spring boot
是否存在AnnotationUtils.isCandidateClass()
该方法即可,如果有则调用AnnotationUtils.isCandidateClass()
,否则则调用!isSpringContainerClass
方法
代码实现比较简单,这里就直接给出了
private boolean validationAnnotation(Class<?> targetType) {
boolean nonAnnotatedClassesFlag = !this.nonAnnotatedClasses.contains(targetType);
// 判断是否存在isCandidateClass 方法 存在这调用该方法,否则调用isSpringContainerClass方法
boolean isCandidateClassFlag = ClassUtils.hasMethod(AnnotationUtils.class, "isCandidateClass", Class.class, Class.class) ?
AnnotationUtils.isCandidateClass(targetType, Listener.class) : !isSpringContainerClass(targetType);
return nonAnnotatedClassesFlag && isCandidateClassFlag;
}
private static boolean isSpringContainerClass(Class<?> clazz) {
return (clazz.getName().startsWith("org.springframework.") &&
!AnnotatedElementUtils.isAnnotated(ClassUtils.getUserClass(clazz), Component.class));
}
总结
总的来说就是判断该方法是否存在,存在则调用,不存在则调用旧版本方法。可以看到要是我们熟悉一些框架的源码,对于我们遇到了类似的问题有非常好的解决思路,所以学习源码还是非常有必要的
原文始发于微信公众号(小奏技术):简单聊聊spring boot自研sdk版本兼容问题如何解决
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/29909.html