坑爹的spring-boot-devtools,你还在用吗
最近开发了一个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
更多推荐
所有评论(0)