关于springboot:聊聊springboot自动装配出现的TypeNotPresentExceptionProxy异常排查

前言

注释开始前,咱们做个小测试,假如咱们封装了一个springboot starter,其主动拆卸类形如下内容

@Configuration
@EnableConfigurationProperties({ApolloRefreshProperties.class})
public class ApolloRefreshAutoConfiguration  {

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnClass({ConfigService.class})
    public ApolloRefreshService apolloRefreshService(ApolloRefreshProperties properties) {
        return new ApolloRefreshService(properties);
    }
    }

该starter的pom引入的apollo gav是optional

  <dependency>
            <groupId>com.ctrip.framework.apollo</groupId>
            <artifactId>apollo-client</artifactId>
            <version>${apollo-client.version}</version>
            <optional>true</optional>
        </dependency>

我的问题是

在运行环境为jdk8的springboot我的项目引入上述的starter,是否会有问题?

咱们运行一下,发现会呈现

而后咱们不改任何一行代码,把JDK调成11或者以上版本,再运行

我的项目胜利运行。那咱们的修复的第一直觉是不是把JDK8的版本进步。

咱们团队的小伙伴第一工夫也是这么干的,他去和业务团队的技术经理沟通,看他们能不能把JDK8调整成JDK11,而后失去了业务团队技术经理的高度否定,因为他们大部分业务都跑在jdk8,冒然升级成jdk11,也不晓得会不会因为了解决一个问题,而引入其余问题

问题排查

因为这个starter的主动拆卸配置的内容绝对简略,基于老司机的第六感,问题大概率是呈现在@ConditionalOnClass这注解上,于是点开@ConditionalOnClass,他的注解上有如下提醒

他的粗心是,能够在@Configuration classes上平安地指定value(),因为在加载类之前会应用ASM解析正文元数据。当搁置在@Bean办法上时,须要分外小心,请思考在独自的Configuration类中隔离条件,特地是当办法的返回类型与条件的指标匹配时。如果非要用办法注解,倡议应用ConditionalOnClass外面的name字段

于是咱们听官网的倡议,将starter调整如下

@Configuration
@EnableConfigurationProperties({ApolloRefreshProperties.class})
public class ApolloRefreshAutoConfiguration  {

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnClass(name = "com.ctrip.framework.apollo.ConfigService")
    public ApolloRefreshService apolloRefreshService(ApolloRefreshProperties properties) {
        return new ApolloRefreshService(properties);
    }
    }

再次运行,果然不再报错。具体问题起因,我就不班门弄斧了,能够查看官网的issue

https://github.com/spring-projects/spring-boot/issues/27846

https://github.com/spring-projects/spring-boot/issues/17282

总结

首先如果用 @ConditionalOnClass注解,强烈建议应用name属性,而不要用value属性。其次如果有提供组件给其余业务团队应用,要特地关注版本问题,以及做好向下兼容,不然指不定又掉坑了。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理