我使用@Autowired
数百次,但今天我没有得到它,@Autowired
和@Inject
都没有在我刚创建的新项目中工作,我得到了一个着名的错误
无效的属性' jdbcTemplate' bean类[com.xxx.SomeDAO]:Bean property' jdbcTemplate'不可写或具有无效的setter 方法。 setter的参数类型是否与getter的返回类型匹配?
当我在jdbcTemplate
中为SomeDAO
添加setter时,它可以正常工作......
的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;
}*/
}
什么可以通过注释阻止注入?谢谢!
答案 0 :(得分:1)
当使用XML-context以您提供的方式创建bean时,无法使用字段注入。您的类不是任何组件扫描的一部分,因此注释不起作用。因此,我至少可以看到以下选项:
<强> 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。在那里你可以找到所有上述的一个很好的解释!