项目场景:
项目整体使用SSM框架。
问题描述:
在开发过程中,对一个派生类进行修改,需要新增一些数据库操作。该项目是使用SSM的,我们在xml文件中写了SQL,在Dao、DaoImpl中分别进行了接口定义和实现类的实现。
在该派生类中,我们希望调用该数据操作,按照一般思路,根据Spring的依赖注入特性,使用@Resource注解,对Dao对象进行注入,就可以执行该接口下定义的方法了,如:
@Resource
QueryDao qd ;//对dao对象进行注入
..........//省略逻辑代码
Object rs = qd.selectSingleRs(id); // 获取执行结果
但是在代码实际运行过程中,运行到调用dao方法这步时,会抛出NullPointer异常。DeBug发现,qd对象是null的。
这个问题在其他类中没有复现,使用的也是成熟的逻辑,那么问题会出在哪里呢 ?
原因分析:
请大佬来协助分析,发现这个类的逻辑执行过程,是由主流程中,一个分支流程,通过反射进行:
c = Class.forName("com.c.p.f.e.XMLFrom"+propvalue);
Method m=c.getMethod("XML",Object[].class);
大佬指出,通过反射手动生成的类及其类方法,控制权不在Spring上,即没有注册在Spring容器中,这样的类相当于无法使用Spring的注入方法,所以@Resource注入是无效的,这就是空指针的原因。
解决方案:
解决方案也分两种 :
1、放弃通过Dao来使用MyBatis映射,手动获取数据库connection(原生JDBC);
2、手动对反射获取的类对象c,注册到Spring容器中(划重点):
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
//引入这两个类,分别是Autowired注解的依赖和Spring上下文对象类
....
@Autowired
ApplicationContext context ;
//初始化ApplicationContext对象,必须使用@AutoWired,这是ByType的方法,而ByName的@Resource不能注入Spring对象
....
c = Class.forName("com.c.p.f.e.XMLFrom"+propvalue);//反射获取类
Object o = c.newInstance();//获取类的实例
context.getAutowireCapableBeanFactory().autowireBean(o);//对o对象,自动注册到Spring中
经过手动注册,Spring容器中有了相对应的对象,可以在类中使用对应的Spring注解等。
关注不迷路,随时解决各种问题。