Spring 不推荐Field注入,为啥我反对

Spring 不推荐Field注入,为啥我反对

官方原文咋说的

The Spring team generally advocates constructor injection as it enables one to implement application components as immutable objects and to ensure that required dependencies are not null. Furthermore constructor-injected components are always returned to client (calling) code in a fully initialized state.

简单的翻译一下:构造器注入,可以保证

  1. 注入的组件不可变( immutable objects )
  2. 必须的依赖不为空(required dependencies are not null.)
  3. 能够在返回客户端(组件)代码的时候保证完全初始化的状态。

那我就来说我下的看法

首先,注入的组件不可变。如果是field注入,有人随意地在某个方法里更改注入,这都什么人,那这种人可以立刻开除。几乎已经约定俗成的东西,为何要用更改注入方式去约束?

第二,必须的依赖不为空。@Autowired 本身就有required参数,且默认是true,必须的依赖不为空field注入也可以

第三,能够在返回客户端(组件)代码的时候保证完全初始化的状态。这个特点,很多博主用来说明构造器注入可以检查循环依赖。循环依赖是不是个问题有待商榷,不同的项目适用不同的架构,不能一杆子把循环依赖打死。遇到循环依赖,我们是可以通过分层来避免,controller->service->dao三层不够用,可以再分成controller->business->service->dao。但是对于一个大项目下的一个小服务,代码本身就没多少,循环依赖也相对少,没必要为了解决一个小问题把代码划成四层徒增代码量。

这里顺带简单说明下spring如何解决循环依赖的

  1. Spring将一个单例的Bean分为 已创建(created)和 初始化 (instantiated)两个状态,用两个Map来存放。两个Map分别是 singletonObjects 和 earlySingletonObjects
  2. 同时还有有个map (singletonFactories)用于存放Bean的工厂方法 (ObjectFactory),这三个map称为三级缓存
  3. 比如,有两个Bean A和B,A依赖B ,B依赖A。
    1. A 加载时,依次查询singletonFactories、earlySingletonObjects、singletonObjects,找到singletonFactories里A的ObjectFactory调用getObject完成创建,并从singletonFactories删除A的ObjectFactory,将创建好的A (created)放入 earlySingletonObjects
    2. A 开始检查依赖,发现有依赖B,按照步骤1创建B(这里插入步骤3), 将B注入A。这时A初始化完毕,放入singletonObjects。并从earlySingletonObjects删除A。
    3. 在步骤2创建B的过程里,B也开始检查依赖,发现earlySingletonObjects中有A,就取出,将A注入B,B初始化完毕,放入singletonObjects。

而且,就算不用构造器注入,也是可以检查循环依赖的

@Bean
@Order(1)
public BeanFactoryPostProcessor myBeanFactoryPosyProcessor(){
    return beanFactory -> {
        if(beanFactory instanceof DefaultListableBeanFactory){
            ((DefaultListableBeanFactory) beanFactory).setAllowCircularReferences(false);
        }
    };
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值