【问题标题】:@Inject and @Autowired not working whereas injecting with setter works@Inject 和 @Autowired 在使用 setter 注入时不起作用
【发布时间】:2015-02-24 04:38:30
【问题描述】:

我使用@Autowired 数百次,但今天我不明白,@Autowired@Inject 在我刚刚创建的新项目中都没有工作,我得到了著名的错误

bean 类 [com.xxx.SomeDAO] 的无效属性“jdbcTemplate”:Bean 属性“jdbcTemplate”不可写或具有无效的设置器 方法。 setter的参数类型和getter的返回类型是否匹配?

当我在SomeDAO 中添加jdbcTemplate 的设置器时,它可以工作...

applicationContext.xml:

...
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>

<bean id="com.xxx.SomeDAO" class="com.xxx.SomeDAO">
    <property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
...

SomeDAO.java:

import org.springframework.jdbc.core.JdbcTemplate;
import javax.inject.Inject;
//import org.springframework.beans.factory.annotation.Autowired;

public class SomeDAO {

    @Inject // Doesn't work
    //@Autowired // Doesn't work either
    private JdbcTemplate jdbcTemplate;
    ...

    /* Works if I add this setter
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }*/
}

什么可以防止通过注解注入?谢谢!

【问题讨论】:

  • 你试过没有applicationContext.xml中的property元素吗?也许它与那个有冲突。我没有把注解和xml结合起来。
  • 没有属性,只有字段。使用@Autowired 或类似方法的全部意义在于您不再需要在 XML 中指定依赖关系。

标签: java spring dependency-injection


【解决方案1】:

当 bean 以您提供的方式使用 XML 上下文创建时,无法使用字段注入。您的课程不是任何组件扫描的一部分,因此注释不会生效。因此,我至少可以看到以下选项:

1.根据您的示例使用 setter 并删除 @Inject

这是最简单的方法,因为您已准备好代码和 XML。但是,这意味着您的 DAO 必须公开一个不必要的 setter 方法。

2。使用设置 jdbcTemplate 字段的构造函数

在我看来这是一个更好的选择,但这意味着你需要像这样重写 XML:

<bean id="com.xxx.SomeDAO" class="com.xxx.SomeDAO">
    <constructor-arg ref="jdbcTemplate"/>
</bean> 

而且,你的构造函数是这样的:

public class SomeDAO {
    private final JdbcTemplate jdbcTemplate;

    public SomeDAO(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
}

3.添加组件扫描并使用@Autowired(或@Inject)

如果您想充分利用 Spring 的依赖注入功能之美,我认为这是最好的方法。将以下内容添加到您的 XML 上下文中:

<context:component-scan base-package="com.xxx"/>

然后您之前提供的代码应该可以工作了。但是,您可能应该考虑避免字段注入以支持构造函数注入。 opinions differ on this matter 但我发现使用字段注入时代码更难测试。

构造函数注入如下所示:

// The component scanner will find this annotation and create 
// the bean (and inject the dependencies)
@Component
public class SomeDAO {
    private final JdbcTemplate jdbcTemplate;

    @Autowired // enables constructor-injection
    public SomeDAO(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
}

我个人更喜欢替代#3,因为它干净、基于 Java(实际上不需要 XML),这也意味着它重构友好,没有字段 magic 发生并且基于构造函数的方法使代码可测试,并且不会暴露任何不必要的 setter 方法。

优秀的Spring Documentation 是了解更多信息的良好起点。在那里你可以找到对上述所有内容的一个很好的解释!

【讨论】:

  • 我确实搞砸了配置,缺少 context:component-scan。我会研究构造函数注入,它有时可能很有用。
猜你喜欢
  • 1970-01-01
  • 2011-11-26
  • 1970-01-01
  • 1970-01-01
  • 2015-10-01
  • 2023-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多