为什么Spring不支持直接的场依赖注入(自动布线除外)?

2022-09-02 10:25:35

我对直接字段依赖注入感兴趣。传统上,Spring支持构造函数注入(向构造函数提供参数)和基于 setter 的注入(在调用时调用 setter)。

但是,Spring 还能够直接注入字段(在没有 setter 方法的情况下设置对象的成员字段),如 用 注释字段来证明。自动布线仅限于“beans”,因此无法注入原始值(尽管这可以通过创建类“java.lang.String”的bean来规避 - 这可以工作,但具有自动布线的正常警告。除此之外,Spring还支持从属性等直接设置成员字段的值。@Autowired@Value

但是,Spring 不允许将属性直接设置为成员字段(不自动布线)。

我的问题是:为什么?

它显然有能力这样做,那么为什么不呢?是否有任何重大的负面副作用可以防止这种情况?还是功能以某种方式受到限制,因此只有自动布线才有意义?它需要比呼叫设置者更大的黑客吗?

请注意,我不想讨论一般拥有二传手和获取者的相对优点,只是Spring做出这一选择的原因。


答案 1

@Autowired注释使用反射使私有字段可访问(请参阅此相关问题)。我可以看到为什么在Spring配置文件中不使用它的三件事。

  1. 由于配置是通过bean属性(getters和setters)进行的,因此您无法真正判断 - 在两者都存在的情况下 - 是否要调用setValue或设置成员值。
  2. 它破坏了封装。您的Spring配置没有理由知道私有成员变量。使用注释是可以的,因为它已经在源代码中了。
  3. 安全问题。限制性更强的安全管理器可能不允许通过反射访问私有字段。

答案 2

我想我自己找到了答案。我转到了Spring源代码,并查看了这些功能是如何实际实现的。这是我的发现:

通过XML设置属性可能是Spring最古老的部分,它非常依赖于“java.beans”类进行内省,属性枚举等。很明显,这些根本不支持现场反省。除此之外,还有类型转换机制,它确定如何将属性值转换为相关属性的合适值。这里没有整齐可分离的碎片。

所有@Autowired等的东西都是在BeanPostProcessor中实现的,它有自己的类型匹配机制,这与类型转换无关。这也是为什么它只注入豆子的原因。对于@Value来说,同样的事情几乎也是如此,它只是在那里当场解决的问题,与财产无关。

因此,添加字段注入支持(特别是对于属性)并不是一件容易的工程工作,因为执行其中一个或另一个操作的代码部分几乎完全独立。

这并不能完全回答“为什么?”,但我认为这是一个更令人信服的解释,说明为什么Spring没有添加直接的字段依赖注入,而不是我听到的其他解释。除非他们有一些根本性的东西来反对它(我怀疑,考虑到他们希望允许配置现有的第三方类,而不仅仅是JavaBeans),那么这只是一个工程工作的问题。


推荐