一、初识
Spring 的自动注入,注解方式就是使用 @Autowired,Spring 会帮助我们自动注入已经使用了 @component、@controller、@service、@repository这些注解标记过的类,从此释放我们的双手,不需要再手动 new 对象了。每个初学者都伸手就是下图的写法:
</p>
二、再探
但是今天看了下智能的 IDE 给的警告信息,瞬间觉得自己之前都是使用的 low 爆了的 BI。
正如上图:其实 Spring 团队建议我们的是,使用构造函数的形式来注入,而不是简单的以成员变量的方式直接注入,即如下图:
那么,这么做有什么好处呢,我们从最基本的点开始着手。
自动注入,是啥意思呢?简言之就是 Spring 会自动帮我们 new 对象,而 new 对象就是调用构造函数,所以,spring 建议我们使用构造函数的形式来注入,但是必须得注意,上图所见的是有参构造,而如果被注入的类里面存在一个无参构造,那么 spring 便会去调用这个无参构造,而不会调用有参构造。
如下 demo,有一个类 AutowiredTarget,内部有有参和无参两种构造同时存在,两种情况都跑一次,结果见下图:
好,我们跑一个极端的例子,AutowiredTarget 这个类里面有两个有参构造会怎么样?我猜会异常,见下图:
果然报错了,毕竟我们使用了两个 @Autowired,其实,它spring 默认的会去找有 @Autowired 注解的构造,没有的话就默认无参构造。
三、进化
其实,说到底, Spring 为什么会建议,或者说是要求我们这么做,其实下图这个 demo 能够很好地阐明缘由:
demo 很简单,项目启动时候异常,缘由也很简单,其实就是一个顺序的问题,
因为注入一个类的时候,内部的构造函数被调用的优先级是高于内部成员变量的,即,上图中的构造函数被注入了,但是此时的 成员变量 people 还没有被赋值(即还没有被注入),所以才有了空指针的异常。
四、总结
洋洋洒洒写了一大段,其实想阐述的就是简单一个观点:
@Autowired 可以对成员变量、方法以及构造函数进行注释,而 spring 强烈建议我们使用构造函数的形式来注入。
缘由就是构造函数的优先级较高,不会出现空指针异常。
另外,Java 类中变量的初始化顺序为:静态变量或静态语句块 –> 实例变量或初始化语句块 –> 构造方法 –> @Autowired。
最后,spring 建议我们使用 final,我想有可能是因为“注入”的这个过程是单例的吧。