Java中@Autowired写在成员变量上和构造函数上的区别??

Spring的强大我们都知道,这里就遇到的一个疑问写一篇文章。
我们都知道:@Autowired 可以对成员变量、方法以及构造函数进行注释。那么对成员变量和构造函数进行注释又有什么区别呢?

一、下面先看下实例:

public class Test{
	//方式一:用在成员变量上
	@Autowired
	private A a;

	//方式二:用在构造函数上---推荐
	private final B b;
	@Autowired
	public Test(B b) {
		this.b = b;
	}
}

在使用Sring的@Autowired注解时,你可能会收到如下提醒:
Spring Team recommends “Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies”.
翻译:Spring Team建议“在bean中始终使用基于构造函数的依赖项注入。总是对强制依赖项使用断言”。
注意:断言,Java基础的一个内容,具体内容可以参考《java学习笔记之断言(Assertion)》

理解:
方式一:
@Autowired写在成员变量上,相当于在配置文件中配置bean,并且使用setter注入。
方式二:
@Autowired写在构造函数上,相当于使用构造函数进行依赖注入。

二、再来个实例:

public class Test{
    @Autowired
    private A a;
    
    private String prefix;
    
    public Test(A a) {
    	this.prefix= a.getExcelPrefix();
    }
}

上面这种情况就会报错了,报错信息可能会像下面:
  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时构造方法出错,在构造方法里抛出了空指针异常。

三、总结:

区别主要在于加载顺序上,@autowired写在变量上的注入要等到类完全加载完,才会将相应的bean注入,而变量是在加载类的时候按照相应顺序加载的,所以变量的加载要早于@autowired变量的加载,那么给变量prefix 赋值的时候所使用的a,其实还没有被注入,所以报空指针,而使用构造器就在加载类的时候将a加载了,这样在内部使用a给prefix 赋值就完全没有问题。

Java变量的初始化顺序为:
静态变量或静态语句块–>实例变量或初始化语句块–>构造方法中的变量–>@Autowired下的变量
  
该内容在我的另一篇文章中也有简单提及《小码农的十万个为什么!!!(持续更新)》

以梦为马,以汗为泉,不忘初心,不负韶华。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值