zoukankan      html  css  js  c++  java
  • @Autowired的使用:推荐对构造函数进行注释

    @Autowired的使用:推荐对构造函数进行注释

      在编写代码的时候,使用@Autowired注解是,发现IDE报的一个警告,如下:

      Spring Team recommends "Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies".

      翻译:
        Spring建议”总是在您的bean中使用构造函数建立依赖注入。总是使用断言强制依赖”。

    这段代码警告原来的写法是:

    @Autowired
    private EnterpriseDbService service;

    建议后写成下面的样子:

    private final EnterpriseDbService service;

    @Autowired
    public EnterpriseDbController(EnterpriseDbService service) {
       this.service = service;
    }

      奇怪,为何会有这样的建议。

      我们知道:@Autowired 可以对成员变量、方法以及构造函数进行注释。那么对成员变量和构造函数进行注释又有什么区别呢?

      @Autowired注入bean,相当于在配置文件中配置bean,并且使用setter注入。而对构造函数进行注释,就相当于是使用构造函数进行依赖注入了吧。莫非是这两种注入方法的不同。


      以下是:@Autowired和构造方法执行的顺序解析

      先看一段代码,下面的代码能运行成功吗?

    1 @Autowired
    2 private User user;
    3 private String school;
    4 
    5 public UserAccountServiceImpl(){
    6     this.school = user.getSchool();
    7 }

      答案是不能。

      因为Java类会先执行构造方法,然后再给注解了@Autowired 的user注入值,所以在执行构造方法的时候,就会报错。

      报错信息可能会像下面:
      Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name '...' defined in file [....class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [...]: Constructor threw exception; nested exception is java.lang.NullPointerException
      报错信息说:创建Bean时出错,出错原因是实例化bean失败,因为bean时构造方法出错,在构造方法里抛出了空指针异常。

      解决办法是,使用构造器注入,如下:

    1 private User user;
    2 private String school;
    3 
    4 @Autowired
    5 public UserAccountServiceImpl(User user){
    6     this.user = user;
    7     this.school = user.getSchool();
    8 }

      可以看出,使用构造器注入的方法,可以明确成员变量的加载顺序

      PS:Java变量的初始化顺序为:静态变量或静态语句块–>实例变量或初始化语句块–>构造方法–>@Autowired

      参考:http://blog.csdn.net/ruangong1203/article/details/50992147


      那么最开始Spring建议,为何要将成员变量加上final类型呢?

      网上有解释如下:spring配置默认的bean的scope是singleton,也就是启动后一直有。通过设置bean的scope属性为prototype来声明该对象为动态创建。但是,如果你的service本身是singleton,注入只执行一次。

      @Autowired本身就是单例模式,只会在程序启动时执行一次,即使不定义final也不会初始化第二次,所以这个final是没有意义的吧。

      可能是为了防止,在程序运行的时候,又执行了一遍构造函数;

      或者是更容易让人理解的意思,加上final只会在程序启动的时候初始化一次,并且在程序运行的时候不会再改变。

      不过这种写法,我还是蛮喜欢的!

  • 相关阅读:
    利用DTrace实时检测MySQl
    改进MySQL Order By Rand()的低效率
    RDS for MySQL查询缓存 (Query Cache) 的设置和使用
    RDS For MySQL 字符集相关说明
    RDS for MySQL 通过 mysqlbinlog 查看 binlog 乱码
    RDS for MySQL Mysqldump 常见问题和处理
    RDS for MySQL Online DDL 使用
    RDS MySQL 表上 Metadata lock 的产生和处理
    RDS for MySQL 如何使用 Percona Toolkit
    北京已成为投融资诈骗重灾区:存好骗子公司黑名单,谨防上当!
  • 原文地址:https://www.cnblogs.com/lxl57610/p/7783167.html
Copyright © 2011-2022 走看看