Administrator
发布于 2022-09-24 / 73 阅读
0
0

@Autowired写在成员变量上和构造函数上的问题

刷知乎刷到了个一段关于代码的评价问题,里面有一句是说

Should use @Autowired on constructor rather than member definition. 
IDEA would warn that and explain that it's for a better DI.

翻译过来就是:
应在构造函数上使用@Autowired而不是成员定义。
IDEA会警告这一点,并解释说这是为了更好的DI。

然而我平时的开发做项目都是习惯放在成员变量上的,觉得没啥问题
image-1663985700174

然后网上搜了一下说,官方推荐使用构造器注入啥啥啥的

image-1663986371353

如上图这样,至于@Autowired注解可以不标注,因为说Spring4.3+之后,constructor注入支持非显示注入方式。
至于构造方法上的要注入的组件呢,只要你在容器中有,就会默认去容器中找,这是学SpringBoot的时候雷丰阳老师教过的

至于为甚么推荐使用这样的而不是直接使用注解,网上有人举有一个例子,比如你要进行如下的操作:
image-1663986664289

在项目启动的时候会报空指针异常:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate 
Caused by: java.lang.NullPointerException: null
	

原因是说加了@Autowired注解的组件注入要在类加载完成之后执行,但变量的加载又是在类加载的时候按一定顺序执行的,所以prefix会报空指针异常,因为a都还没有注入。

然后又引出了一个无法解决循环依赖问题:

image-1663987990345

个人想了一下,没有太深入,可能是他说法有问题,如果有循环依赖问题,应该不是构造器注入的锅吧,只能说构造器也无法解决循环依赖问题,或者说他本身就有循环依赖问题,且使用了setter注入解决了问题。
至于对循环依赖的解决办法,则如图所说,有一下几种:
1. 重新设计,避免循环依赖
2. @Lazy延迟加载
3. setter注入
4. 使用@PostConstruct
5. 等等,其他的不熟悉,没怎么见过,不补充了


评论