简单聊聊spring boot自研sdk版本兼容问题如何解决

  • A+
所属分类:Spring Boot

背景

最近在团队内部写了一个简单的基于spring boot的sdk,我这边使用的spring boot版本为2.4.2
然后在sdk稳定上线后其他项目也想使用,在使用中发现引入sdk后起不来。报错
简单聊聊spring boot自研sdk版本兼容问题如何解决
这里可以看到报错信息也很明显就是AnnotationUtils.isCandidateClass()方法不存在,而方法AnnotationUtils.isCandidateClass又是我直接使用了 spring boot的工具类
简单聊聊spring boot自研sdk版本兼容问题如何解决

如果以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自研sdk版本兼容问题如何解决

知道了替代方法我们的处理方式就简单了,低版本的spring boot我直接调用!isSpringContainerClass(targetType)方法即可。那么问题又变成了如何判断spring boot版本问题

如果你对Spring Boot条件注解ConditionalOnJava熟悉的话就可以参考这种方式去实现
ConditionalOnJava需要判断当前jdk版本,而他的做法就是通过特定jdk版本有不同方法去判断jdk版本的
简单聊聊spring boot自研sdk版本兼容问题如何解决

所以我们只需要判断当前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));
    }

总结

总的来说就是判断该方法是否存在,存在则调用,不存在则调用旧版本方法。可以看到要是我们熟悉一些框架的源码,对于我们遇到了类似的问题有非常好的解决思路,所以学习源码还是非常有必要的

w3cjava

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: