lus*_*uso 31 java spring dependency-injection
anotate @Autowired与某个属性或在setter中执行此操作有什么区别?
据我所知他们都有相同的结果,但有没有理由使用一个而不是另一个?
更新(更简洁)
这有什么区别
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
public class TextEditor {
private SpellChecker spellChecker;
@Autowired
public void setSpellChecker( SpellChecker spellChecker ){
this.spellChecker = spellChecker;
}
public void spellCheck() {
spellChecker.checkSpelling();
}
}
Run Code Online (Sandbox Code Playgroud)
还有这个
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
public class TextEditor {
@Autowired
private SpellChecker spellChecker;
public TextEditor() {
System.out.println("Inside TextEditor constructor." );
}
public void spellCheck(){
spellChecker.checkSpelling();
}
}
Run Code Online (Sandbox Code Playgroud)
SMA*_*SMA 20
使用@Autowired注释,您不需要setter方法.一旦你的bean的构造函数完成了分配/创建对象,Spring将扫描这个注释并注入你注释的对象实例.
如果您有setter,如果您仍在使用xml配置,则应明确设置属性.
话虽如此,你可以使用autowired注释来注释你的构造函数和setter方法,我更喜欢这样,因为这会让我有灵活性以后离开Spring(虽然我不会这样做).
Bar*_*cki 18
有时您需要A类的实例,但不要在类的字段中存储A. 你只需要A来执行一次性操作.或者,使用A获取B的实例,并在字段中存储B.
在这些情况下,setter(或构造函数)autowire将更适合您.您将没有未使用的类级别字段.
具体示例:您需要构造RabbitTemplate(一个向RabbitMQ发送消息的对象)要构造它,您需要ConnectionFactory http://docs.spring.io/spring-amqp/docs/latest_ga/api/org/springframework/amqp/兔/型芯/ RabbitTemplate.html#RabbitTemplate-org.springframework.amqp.rabbit.connection.ConnectionFactory-
您不需要存储ConnectionFactory.在这种情况下,代码看起来像这样:
Class MyClass {
private RabbitTemplate template;
@Autowired
void setConnectionFactory(ConnectionFactory c) {
template=new RabbitTemplate(c);
}
}
Run Code Online (Sandbox Code Playgroud)
...比直接自动装配ConnectionFactory字段更能为您服务.
在此示例中,构造函数级别的自动装配会更好,因为您的对象将始终完全构造.很明显,ConnectionFactory是一个强制依赖,而不是一个可选的依赖.
ACV*_*ACV 10
自动装配有 3 种类型:
@Autowired
private MyService service;
Run Code Online (Sandbox Code Playgroud)
@Autowired注释:class MyController {
private final MyService service;
public MyController(MyService service) {
this.service = service;
}
}
Run Code Online (Sandbox Code Playgroud)
private MyService service;
@Autowired
public void setService(MyService service) {
this.service = service;
}
Run Code Online (Sandbox Code Playgroud)
建议使用基于构造函数,如果不可能的话,使用基于设置器,最后基于属性。
为什么?
首先,因为在基于构造函数中,您甚至不使用任何 Spring 注释。这可以帮助您过渡到不同的框架。
其次,基于构造函数或设置器,使单元测试变得更加容易。您不需要使用任何 Spring 特定的测试工具,只需使用 Junit 和 Mockito。
第三,基于构造函数很好,因为您可以将属性声明为final而不公开设置器,这有助于类的不变性和线程安全性。
如果在属性上使用@Autowired注解,spring 将使用 spring.xml 启动该属性。在这种情况下,您不需要 setter。
如果在setter上使用@Autowired注解,则指定 spring 它应该使用此 setter 方法启动此属性,您可以在其中添加自定义代码,例如使用此属性初始化其他一些属性。
示例用法: 在使用 JdbcTemplate 进行 DAO 操作的情况下,需要 DataSource 作为 JdbcTemplate 的输入,但 DataSource 本身不需要作为属性。所以你可以使用 DataSource Setter 通过自动连接 DataSource Setter 来初始化 JdbcTempate。请看下面的代码:
class DaoDemo{
//@Autowired
//private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(DataSource dataSource){
//this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public int getTableRowCount(){
String sql = "SELECT COUNT(*) FROM DEMOTABLE";
//jdbcTemplate.setDataSource(dataSource); //No need to do this as its done in DataSource Setter now.
return jdbcTemplate.queryForObject(sql,Integer.class);
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,dataSource 的唯一用途是在 JdbcTemplate 中传递。因此,在这里创建 dataSource 的属性没有意义。因此,只需在 DataSource bean 的 setter 方法上使用 @Autowired 从 spring.xml 获取其条目并在特定时间使用它。
| 归档时间: |
|
| 查看次数: |
34625 次 |
| 最近记录: |