在一个将由Spring连接的类中使用@Autowired的优缺点是什么?
为了澄清,我正在谈论@Autowired注释,而不是XML中的自动连线.
我可能只是不理解它,但对我来说它几乎看起来像一个反模式 - 你的类开始意识到它们与DI框架相关联,而不仅仅是POJO.也许我是一个贪婪的惩罚,但我喜欢有bean的外部XML配置,我喜欢有明确的布线,所以我确切知道什么是连线在哪里.
很长一段时间以来,我一直认为有一个"集中式,声明式,配置"的价值,就像我们以前用过的xml文件一样.然后我意识到文件中的大多数东西都不是配置 - 它在开发之后从未改变过.然后我意识到,"集中"只有在非常小的系统价值-只有在小型系统会你永远能够神交配置文件作为一个整体.当相同的"布线"大部分被代码中的依赖项复制时,整体理解布线的真正价值是什么?所以我唯一保留的是元数据(注释),这仍然是一种声明式的.这些从来没有在运行时改变,他们从来没有 "配置"数据,有人会动态改变 - 所以我认为将其保留在代码中是很好的.
我尽可能多地使用全自动接线.我喜欢它.除非受到枪口威胁,否则我不会回到旧式的春天.我完全偏好的理由@Autowired
随着时间的推移发生了变化.
现在我认为使用自动装配的最重要原因是系统中有一个较少的抽象来跟踪."豆名"实际上已经消失了.事实证明,bean名称仅因xml而存在.因此,完整的抽象间接层(将bean名称"foo"连接到bean"bar"中)将消失.现在我直接将"Foo"接口连接到我的bean,并通过运行时配置文件选择实现.这允许我在跟踪依赖项和实现时使用代码.当我在代码中看到一个自动连接的依赖项时,我可以按下我的IDE中的"转到实现"键,然后是已知实现的列表.在大多数情况下,只有一个实现,我直接进入课堂.能够' 正在使用什么实现(我声称相反的是更接近xml布线的真相 - 有趣的是你的视角如何改变!)
现在你可以说它只是一个非常简单的层,但是我们添加到系统中的每一层抽象都会增加复杂性.我真的不认为xml曾经为我使用的任何系统增加了任何实际价值.
我曾经使用过的大多数系统只有一个生产运行时环境配置.可能还有其他配置用于测试等.
我要说完全自动装配是弹簧上的红宝石:它包含了大多数用例都遵循的正常和常见使用模式的概念.使用XML配置,您可以允许大量一致/不一致的配置使用,这可能是/可能不是.我已经看到了很多xml配置过多的不一致 - 它是否与代码一起被重构?没想到.那些变化是有原因的吗?通常不是.
我们在配置中几乎不使用限定符,并找到了解决这些情况的其他方法.这是我们遇到的一个明显的"劣势":我们稍微改变了我们编码的方式,使其与自动装配交互更顺畅:客户存储库不再实现通用Repository
接口,但我们创建了一个CustomerRepository
扩展的接口Repository
.在子类化方面,有时候还有一两招.但它通常只是指向我们更强的打字方向,我发现这几乎总是一个更好的解决方案.
但是,是的,你正在追求一种主要是春天的特定风格的DI.我们甚至不再为依赖关系制作公共setter(所以你可以说我们在封装/信息隐藏部门中是+1)我们的系统中仍然有一些xml,但xml基本上只包含异常.完全自动装配与xml完美集成.
我们现在唯一需要的是@Component
,@Autowired
其余的都包含在JSR(如JSR-250)中,因此我们不必配合spring.这就是过去发生的事情(这些java.util.concurrent
东西让人想起),所以如果再次发生这种情况,我不会感到惊讶.
对我来说,这是我喜欢/不喜欢Spring和自动接线的.
优点:
自动布线摆脱了令人讨厌的XML配置.
使用注释更容易,允许您使用字段,setter方法或构造函数直接注入.还允许您对注入的bean进行注释和"限定".
缺点:
使用自动连接和注释使您依赖于Spring库,在XML配置中,您可以选择在有或没有Spring的情况下运行.就像你说的那样,你与DI框架联系在一起.
与此同时,我喜欢能够'限定'豆类,对我来说,这使得代码非常混乱.如果你需要在多个地方注入相同的bean,我已经看到了遍及重复的相同字符串名称.对我来说,这似乎有可能出错.
我几乎完全在工作中开始使用自动连接,因为我们非常依赖Spring集成,因为依赖性问题没有实际意义.我参与了一个Spring MVC项目,该项目广泛使用自动布线,并且有点难以绕过我的脑袋.
我认为自动接线是一种后天的品味,一旦你习惯它,你会发现它比XML配置更有效,更轻松,更难以使用.
在我们的大项目中,我们正在从@Autowire切换回XML配置.问题是自举性能非常低.自动装配扫描程序从自动装配搜索类路径加载所有类,因此,在Spring初始化期间会急切地加载许多类.
关于切换环境的讨论很少.我参与其中的大多数项目都是根据我们正在处理的环境注入依赖项的真正问题.使用xml配置,使用Spring EL非常简单,我不知道任何带有注释的好解决方案.我刚想出一个:
@Value("#{${env} == "production" ? realService : dummyService}") private SomeService service;
它应该工作,但不是一个很好的解决方案imho.