Spring自动装配为抽象类提供空bean

Posted

技术标签:

【中文标题】Spring自动装配为抽象类提供空bean【英文标题】:Spring autowiring gives null bean for Abstract class 【发布时间】:2017-03-14 23:15:03 【问题描述】:

我正在尝试将 JDBCTemplate 注入(Autowire)到我的 Dao 类中,这是一个“抽象类”,这不起作用,因为 spring 正在为 JDBCTemplate 提供空 bean。

public abstract class SSODaoImpl extends NamedParameterJdbcDaoSupport implements  SSODao

    public SSODaoImpl()

    
    @Autowired //giving null jdbcTemplate
    public SSODaoImpl(JdbcTemplate jdbcTemplate)
    super.setJdbcTemplate(jdbcTemplate);
    

SSODaoImpl 扩展了我的许多其他 DAO,如下所示

@Repository("askBenefitsDAO")
public class AskBenefitsSSODaoImpl extends SSODaoImpl

我在文件 JDBCContext.xml 中创建了 bean,并在 web.xml 中引用了它

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
     <property name="jndiName" value="java:comp/env/jndi/hpdb_hrdb"/>
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource"/>
</bean>

Web.xml

<context-param>
    <param-name> /WEB-INF/spring/JDBCTemplate/JDBCContext.xml</param-value>       
</context-param> 

启动应用程序时来自 spring 的错误消息

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'askBenefitsDAO' defined in file [AskBenefitsSSODaoImpl.class]: 
Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: 'dataSource' or 'jdbcTemplate' is required

上述设置适用于“非抽象类”设置。请帮我解决这个问题,让我知道我做错了什么

【问题讨论】:

我不确定这与抽象类有关。 JdbcTemplate 在其构造函数中采用javax.sql.DataSource。从 xml 中,构造函数参数引用 dataSource 但 dataSource 不是javax.sql.DataSource @Andrew S 我参考了以下链接link 【参考方案1】:

原因是因为 spring 没有直接调用您的 SSODaoImpl 类的构造函数,而是 在 Spring 实例化 AskBenefitsSSODaoImpl 类 时发生了它的构造函数的调用,并且因此 Spring 无法将 jdbcTemplate 绑定到您的 SSODaoImpl 类。

你可以通过修改你的代码来实现这一点:

@Repository("askBenefitsDAO")
public class AskBenefitsSSODaoImpl extends SSODaoImpl
@Autowired 
    public AskBenefitsSSODaoImpl(JdbcTemplate jdbcTemplate)
    super(jdbcTemplate);
    



public abstract class SSODaoImpl extends NamedParameterJdbcDaoSupport implements  SSODao

    public SSODaoImpl()

    
    public SSODaoImpl(JdbcTemplate jdbcTemplate)
    super.setJdbcTemplate(jdbcTemplate);
    

【讨论】:

以上是关于Spring自动装配为抽象类提供空bean的主要内容,如果未能解决你的问题,请参考以下文章

Spring随笔-bean装配-自动装配

spring装配---处理自动装配的歧义性

Spring-处理自动装配的歧义性

装配Bean

Spring实战自动装配的歧义性

Java配置类装配bean