Spring深入浅出(一):@Autowired的究极奥义

Spring 的一大特性:BI,我们最常用的就是使用 @Autowired 注解的方式来实现自动注入,但是其中还是有一些些玄机可言的。

一、初识

Spring 的自动注入,注解方式就是使用 @Autowired,Spring 会帮助我们自动注入已经使用了 @component、@controller、@service、@repository这些注解标记过的类,从此释放我们的双手,不需要再手动 new 对象了。每个初学者都伸手就是下图的写法:

autowired01.png</p>

二、再探

但是今天看了下智能的 IDE 给的警告信息,瞬间觉得自己之前都是使用的 low 爆了的 BI。

autowired02.png

正如上图:其实 Spring 团队建议我们的是,使用构造函数的形式来注入,而不是简单的以成员变量的方式直接注入,即如下图:

autowired03.png

那么,这么做有什么好处呢,我们从最基本的点开始着手。

自动注入,是啥意思呢?简言之就是 Spring 会自动帮我们 new 对象,而 new 对象就是调用构造函数,所以,spring 建议我们使用构造函数的形式来注入,但是必须得注意,上图所见的是有参构造,而如果被注入的类里面存在一个无参构造,那么 spring 便会去调用这个无参构造,而不会调用有参构造。

如下 demo,有一个类 AutowiredTarget,内部有有参和无参两种构造同时存在,两种情况都跑一次,结果见下图:

autowired04.png

1501036330159048.png

好,我们跑一个极端的例子,AutowiredTarget 这个类里面有两个有参构造会怎么样?我猜会异常,见下图:

autowired06.png

果然报错了,毕竟我们使用了两个 @Autowired,其实,它spring 默认的会去找有 @Autowired 注解的构造,没有的话就默认无参构造。

三、进化

其实,说到底, Spring 为什么会建议,或者说是要求我们这么做,其实下图这个 demo 能够很好地阐明缘由:

demo 很简单,项目启动时候异常,缘由也很简单,其实就是一个顺序的问题,

因为注入一个类的时候,内部的构造函数被调用的优先级是高于内部成员变量的,即,上图中的构造函数被注入了,但是此时的 成员变量 people 还没有被赋值(即还没有被注入),所以才有了空指针的异常。

四、总结

洋洋洒洒写了一大段,其实想阐述的就是简单一个观点:

@Autowired 可以对成员变量、方法以及构造函数进行注释,而 spring 强烈建议我们使用构造函数的形式来注入

缘由就是构造函数的优先级较高,不会出现空指针异常。

另外,Java 类中变量的初始化顺序为:静态变量或静态语句块 –> 实例变量或初始化语句块 –> 构造方法 –> @Autowired。

最后,spring 建议我们使用 final,我想有可能是因为“注入”的这个过程是单例的吧。




------ 本文结束 感谢阅读 ------
0%