最近开发了一个sdk,给项目组的人用,我自己本地测试的时候正常,但是别人引入以后一使用就报NoSuchBeanDefinitionExceprion。

代码逻辑很简单,就是在根据配置的类动态获取spring bean去执行,封装了一个SpringUtil类,代码如下:

mport org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (SpringUtil.applicationContext == null) {
            SpringUtil.applicationContext = applicationContext;
        }
    }

    /**
     * 获取applicationContext
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 通过name获取 Bean.
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /**
     * 通过class获取Bean.
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 通过name,以及Clazz返回指定的Bean
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

}

通过调用getBean(Class clazz)这个方法获取Bean。

开始怀疑是包扫描啥的没配好,但是检查了是没问题的,而且通过actuator的beans端点去看,bean是确实存在的。

没啥头绪只能硬着头皮去debug代码,枯燥的源码就不在此叙述了,最终定位到是对比两个Class类的时候,虽然是同一个类,但是类加载器不同,导致匹配不上。这两个类加载器一个是AppClassLoader,一个是RestartClassLoader。如下图:
在这里插入图片描述

百度一下RestartClassLoader,找到下面这篇文章:
spring-boot-devtools 不同ClassLoader引起的问题

项目用的gradle构建,通过在build.gradle文件里添加配置排除spring-boot-devtools依赖,问题解决。

configurations {
    compile.exclude module: 'spring-boot-devtools'
}

由于我平时都不用devtools的,我负责的项目都会直接把这个依赖给排除掉,所以我自己运行的时候也没问题。

在这里实在忍不住对devtools进行一番吐槽,网上的文章基本都是吹嘘有多好用的,有些甚至还说能热部署。

但是我自己在以前的实践中,发现这玩意是真没用。不引入它的情况下,我修改了一个方法(不修改方法的签名这些),直接ctrl+shift+F9对修改的类进行recompile,就能立马进行重载,修改的内容直接生效,不需要重启。但是引入了它,好家伙,我一编译就会立马触发"重启"(不知道是重启还是重载)。虽然吹嘘的都说只需要重新加载自定义加载的那些类,速度很快,但是我实际使用的时候发现其实挺慢的(就是因为忍不了所以我从来不用)。

一个没啥实际作用(实际是副作用)的东西,百度一下居然都是吹嘘的,都说建议使用,我真是感到无语。

以上都是自己踩过坑以后的一些想法,如有不对,欢迎指正。

网上看到使用spring-boot-devtools导致的一些问题:
spring-boot-devtools和redis同时存在引起的类强转失败问题
springboot 整合 热部署devtools 的一个bug

GitHub 加速计划 / de / devtools
24.6 K
4.14 K
下载
vuejs/devtools: Vue.js 开发者工具,这是一个浏览器插件,可以安装在 Chrome 和 Firefox 等现代浏览器中,用于调试 Vue 应用程序,提供了组件树查看、状态快照、时间旅行等高级调试功能。
最近提交(Master分支:3 个月前 )
79116147 - 4 个月前
f0359002 - 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐