问题描述:
最近在开发一个SpringBoot项目的时候,自己写了组件,以打成Jar包的形式引入到SpringBoot项目中使用,而组件中有一块是根据classname去根据Spring上下文ApplicationContext对象获取SpringBoot项目中注入好的Bean,而就是因为这样一个不起眼的一行代码
Object obj = applicationContext.getBean( Class.forName( className ) );
导致系统每次启动报错,无法在Spring上下文中找到相关对象.......
问题排查:
我在SpringBoot项目中创建了一个测试类,在组件触发之前调用applicationContext.getBean( Class.forName( className ) );,而这段代码是可以正常获取到对象的。
开始怀疑是不是类路径写错了,经过对比并没有,经过一段时间折腾DEBUG,实在不知道问题出在哪里了,后来改了一下组件将组件Class.forName得到的class传出来,然后在SpringBoot项目中对比:
System.out.println( XXX.class == clazz );
System.out.println( XXX.class.equals( clazz ) );
clazz是组件Class.forName得到的class,这两段代码打印出来都是false。瞬间找到问题所在!但是又不只如何解决,怎么会SpringBoot项目中Class.forName("a.b.c.Demo")与组件中Class.forName("a.b.c.Demo")得出来的Class不一致!这个问题暂时不深入了解,先把这个问题解决
解决方案:
组件中创建一个接口类
public interface ISpringBeanService {
public Object getBean(String className) throws ClassNotFoundException;
}
SpringBoot项目中建立该接口类的实现类
@Component
public class SpringBeanServiceBean implements ISpringBeanService {
@Resource
private ApplicationContext applicationContext;
@Override
public Object getBean(String className) throws ClassNotFoundException {
return applicationContext.getBean(Class.forName(className));
}
}
然后在使用组件的时候,不传入ApplicationContext,而传入该实现类,组件中根据该实现类中转一下即可得到Spring上下文注入好的对象!
另外:
希望有高人解答一下为什么SpringBoot中Class.forName的类与引入组件(Jar包)用Class.forName得出的class不同?