Spring XML配置中如何正确注入UploadDao至DemoHandler解决空指针
我尝试通过XML配置将uploadDao注入到DemoHandler Bean中,但uploadDao始终为Null。当前WebUploadServiceImpl会调用DemoHandler的方法,若通过新增参数传递uploadDao,需重构多个复用该方法的类,且该参数对其他类无关。请问如何正确实现uploadDao在DemoHandler中的注入?
当前配置与代码
Spring XML配置
<bean id="wuService" class="com.abcd.service.WebUploadServiceImpl"> <property name="uploadDao" ref="uploadDao" /> <property name="webHandlers"> <set> <bean class="com.abcd.service.handler.DemoHandler" /> </set> </property> </bean>
DemoHandler代码
public class DemoHandler { private UploadDao uploadDao; public List handleM(...) { ... Period period = uploadDao.anyMethod(..); // 此处uploadDao为Null ... } }
首先要明确:你之前的配置里,DemoHandler是作为webHandlers集合的内部Bean存在的,Spring不会自动为内部Bean注入依赖,必须显式配置,或者把它转为Spring容器管理的独立Bean。下面是几种不用重构方法参数的可行方案:
方案1:直接在内部Bean中配置注入
最简单的方式就是在定义DemoHandler内部Bean时,显式添加property标签注入uploadDao,同时要确保DemoHandler有对应的setter方法:
第一步:给DemoHandler添加setter方法
public class DemoHandler { private UploadDao uploadDao; // 必须添加这个setter,Spring通过它完成注入 public void setUploadDao(UploadDao uploadDao) { this.uploadDao = uploadDao; } public List handleM(...) { ... Period period = uploadDao.anyMethod(..); ... } }
第二步:修改XML配置
<bean id="wuService" class="com.abcd.service.WebUploadServiceImpl"> <property name="uploadDao" ref="uploadDao" /> <property name="webHandlers"> <set> <bean class="com.abcd.service.handler.DemoHandler"> <!-- 显式注入uploadDao到DemoHandler --> <property name="uploadDao" ref="uploadDao" /> </bean> </set> </property> </bean>
方案2:将DemoHandler定义为独立Bean
如果DemoHandler后续可能被其他组件复用,或者你想让它的配置更清晰,可以把它定义为独立的Spring Bean,然后在webHandlers集合中引用它:
XML配置修改
<!-- 先定义独立的DemoHandler Bean,完成依赖注入 --> <bean id="demoHandler" class="com.abcd.service.handler.DemoHandler"> <property name="uploadDao" ref="uploadDao" /> </bean> <bean id="wuService" class="com.abcd.service.WebUploadServiceImpl"> <property name="uploadDao" ref="uploadDao" /> <property name="webHandlers"> <set> <!-- 引用已经配置好的demoHandler Bean --> <ref bean="demoHandler" /> </set> </property> </bean>
同样,这也需要DemoHandler有uploadDao的setter方法。
方案3:改用注解注入(如果项目允许)
如果你的项目支持Spring注解,可以大幅简化配置,不用写繁琐的XML:
第一步:给DemoHandler添加注解
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component // 标记为Spring组件,让容器自动扫描创建Bean public class DemoHandler { @Autowired // 自动注入uploadDao,不需要写setter private UploadDao uploadDao; public List handleM(...) { ... Period period = uploadDao.anyMethod(..); ... } }
第二步:XML中开启组件扫描
<!-- 扫描指定包下的注解组件,替换成你的实际包路径 --> <context:component-scan base-package="com.abcd.service.handler" /> <bean id="wuService" class="com.abcd.service.WebUploadServiceImpl"> <property name="uploadDao" ref="uploadDao" /> <property name="webHandlers"> <set> <!-- 引用通过@Component生成的demoHandler Bean --> <ref bean="demoHandler" /> </set> </property> </bean>
甚至可以给WebUploadServiceImpl的webHandlers字段添加@Autowired,让Spring自动注入所有Handler类型的Bean,彻底去掉XML里的集合配置。
你之前的配置中,DemoHandler是作为wuService的内部Bean被创建的,Spring的依赖注入默认只会处理顶级Bean的属性,不会主动递归处理内部Bean的依赖。所以DemoHandler的uploadDao没有被注入,始终为null。
内容的提问来源于stack exchange,提问作者Harry

