Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java spring@Autowire属性与setter_Java_Spring_Dependency Injection - Fatal编程技术网

Java spring@Autowire属性与setter

Java spring@Autowire属性与setter,java,spring,dependency-injection,Java,Spring,Dependency Injection,anotate@Autowired到属性或在setter中执行之间有什么区别 据我所知,它们都有相同的结果,但有什么理由使用一个而不是另一个呢 更新(更简洁) 这两者之间有区别吗 package com.tutorialspoint; import org.springframework.beans.factory.annotation.Autowired; public class TextEditor { private SpellChecker spellChecker;

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();
   }
}
还有这个

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();
   }
}

使用
@Autowired
注释,您不需要setter方法。一旦bean的构造函数完成了对象的分配/创建,Spring将扫描该注释并注入您注释的对象实例

而如果您有setter,并且仍然在使用XMLConfig,则应该显式地设置属性


话虽如此,您可以使用autowired注释对构造函数和setter方法进行注释,我更愿意这样做,因为这将给我以后离开Spring的灵活性(尽管我不会这么做)

自动布线在整个项目中一致使用时效果最佳。如果通常不使用自动连接,那么使用它仅连接一个或两个bean定义可能会让开发人员感到困惑。使用字段上的@Autowired,您不需要setter方法,这一方面使类更小、更易于阅读,但另一方面使模拟类更难看

属性和构造函数参数设置中的显式依赖项始终覆盖自动关联。不能自动关联所谓的简单属性,如原语、字符串和类(以及此类简单属性的数组)。这一限制是故意造成的

自动布线不如显式布线精确。Spring会小心地避免猜测,如果出现歧义,可能会产生意外的结果,Spring管理的对象之间的关系将不再明确记录

布线信息可能不适用于可能从Spring容器生成文档的工具


容器中的多个bean定义可能与要自动连接的setter方法或构造函数参数指定的类型匹配。对于数组、集合或映射,这不一定是问题。但是,对于期望单个值的依赖项,这种模糊性不是任意解决的。如果没有唯一的bean定义可用,将引发异常。

如果可以,应避免使用setter。如果你不需要它,当它不存在时会更好,对吗

我个人更喜欢Guice允许我写作

public class TextEditor {
   private final SpellChecker spellChecker;

   @Inject public TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void spellCheck(){
      spellChecker.checkSpelling();
   }
}

这更进一步:使用
final
字段,我知道它永远不会改变,我得到了。

有时您需要类a的实例,,但您不在类的字段中存储a
您只需要一个实例来执行一次性操作。或者,您使用一个实例来获取B的一个实例,并将B存储在字段中

在这些情况下,设置器(或构造函数)autowire将更适合您
您将没有未使用的类级别字段

具体例子:
您需要构造RabbitTemplate(一个向RabbitMQ发送消息的对象) 要构建它,您需要ConnectionFactory

您不需要存储该ConnectionFactory。在这种情况下,代码如下所示:

Class MyClass {
private RabbitTemplate template;

@Autowired 
void setConnectionFactory(ConnectionFactory c) {
    template=new RabbitTemplate(c);
}
}
…将比直接自动连接ConnectionFactory字段更好地为您服务


在本例中,构造函数级别的自动连接会更好,因为您的对象总是完全构造的。很明显,ConnectionFactory是一个强制依赖项,而不是可选依赖项。

如果在属性上使用
@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);

}

在上面的代码中,dataSource的唯一用途是在JdbcTemplate中传递。因此,创建dataSource的属性在这里没有意义。因此,只需使用DataSourceBean的@Autowired on setter方法从spring.xml获取其条目,并在特定时间使用它本身

有一种情况是,在可选属性上使用@Autowired将不起作用

如果要使用该属性进行一些初始化,则在调用构造函数之前可能不会设置该属性,并且由于它是可选的,因此不能将其作为参数放入构造函数中


在这种情况下,最好使用@Autowired setter方法,以便在自动连接属性后执行初始化。

有3种自动连接类型:

  • 基于属性
  • 基于构造函数的。注意:在Spring Boot中,在这种情况下,您甚至不需要
    @Autowired
    注释:
  • 基于Setter的:
建议使用基于构造函数的,如果不可能,则使用基于Setter的,最后是基于属性的

为什么?

  • 首先,因为在基于构造函数的应用程序中,您甚至不使用任何Spring注释。这有助于您过渡到不同的框架

  • 第二,基于构造函数或Setter,使单元测试更容易。您不需要使用任何特定于Spring的测试工具,只能使用Junit和Mockito

  • 第三,基于构造函数很好,因为您可以将属性声明为
    final
    ,而不公开setter,这有助于类的不变性和线程安全性


我不知道为什么要回答这个问题
@Autowired
private MyService service;
class MyController {
 private final MyService service;

 public MyController(MyService service) {
  this.service = service;
 }
}
private MyService service;


@Autowired
public void setService(MyService service) {
 this.service = service;
}