目录
- 问题背景
- @Autowired和构造方法执行顺序差异
- 解决方案
- 为什么要加final?
问题背景
使用@Autowired注解时,发现IDEA报了一个 warning!
追求极致的程序员怎么受得了这玩意?
- 还得再点击那三小点点!然后继续点!
Spring Team recommends “Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies”.
和阿里编码规范推荐似的,Spring团队推荐又来了:总是在您的bean中使用构造函数建立依赖注入。总是使用断言强制依赖”。
直接alt+enter
写成这样子
好了,终于没大波浪了。
可是对真理充满追求的程序员又开始抓狂了,为啥这就不警告了呢????
众所周知,@Autowired 可以对成员变量、方法以及构造方法三种方式操作。
那么成员变量和构造方法设置又有什么区别呢?
@Autowired注入bean,相当于在配置文件中配置bean,并且使用setter注入。而对构造方法,就相当于是使用构造函数进行依赖注入了吧。莫非是这两种注入方法的不同???
@Autowired和构造方法执行顺序差异
先看一段代码,下面的代码能运行成功吗?
不能。
因为Java类会先执行构造方法,然后再给注解了@Autowired 的user注入值。
Java变量的初始化顺序:静态变量或静态语句块–>实例变量或初始化语句块–>构造方法–>@Autowired
所以在执行构造方法时,就会报错。报错信息可能会像
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时构造方法出错,在构造方法里抛NPE。
解决方案
通过构造方法注入
使用构造方法注入,可以明确成员变量的加载顺序。
可细心地程序员不止于此,还有个问题
为什么要加final?
网上解释:
- spring配置默认的bean的scope是singleton,也就是启动后一直有。通过设置bean的scope属性为prototype来声明该对象为动态创建。但是,如果你的service本身是singleton,注入只执行一次。@Autowired本身就是单例模式,只会在程序启动时执行一次,即使不定义final也不会初始化第二次,所以这个final是没有意义的吧。可能是为了防止,在程序运行的时候,又执行了一遍构造函数;
- 或者是更容易让人理解的意思,加上final只会在程序启动的时候初始化一次,并且在程序运行的时候不会再改变。
- 参考
https://blog.csdn.net/ruangong1203/article/details/50992147