使用有什么优点和缺点 @Autowired 在一个由 Spring 连接的类中?

只是为了澄清一下,我正在具体谈论 @Autowired 注释,而不是 XML 中的自动装配。

我可能只是不明白它,但对我来说,这几乎像是一种反模式 - 你的类开始意识到它们与 DI 框架相关,而不仅仅是 POJO。也许我是一个贪图惩罚的人,但我喜欢为 bean 提供外部 XML 配置,并且我喜欢有明确的连接,所以我确切地知道什么连接在哪里。

有帮助吗?

解决方案

很长一段时间以来,我认为有一个<!>“集中式,声明式,配置<!>的价值。就像我们以前用过的xml文件一样。然后我意识到文件中的大部分内容都不是配置 - 它在开发之后从未改变过。然后我意识到<!>“集中<!>”;只在非常小的系统中具有价值 - 只有在小型系统中,您才能够整体地整理配置文件。当相同的<!>“布线<!>”时,整体理解布线的真正价值是什么?大部分是由代码中的依赖项重复?所以我唯一保留的是元数据(注释),这仍然是一种声明式的。这些从不在运行时更改,而且从不 <!> quot; configuration <!> quot;有人会动态改变的数据 - 所以我认为将其保存在代码中是很好的。

我尽可能多地使用全自动布线。我喜欢它。除非受到枪口威胁,否则我不会回到旧式的春天。我完全喜欢@Autowired的理由随着时间的推移而发生了变化。

现在我认为使用自动装配的最重要原因是系统中的抽象少了一个,以便跟踪。 <!>“bean名称<!>”;实际上已经消失了事实证明,bean名称仅因xml而存在。因此,完整的抽象间接层(将bean-name <!>“foo <!>”连接到bean <!>“; bar <!>”;)的地方消失了。现在我连接<!>“Foo <!>”;直接接口到我的bean,并通过运行时配置文件选择实现。这允许我在跟踪依赖项和实现时使用代码。当我在代码中看到自动连接的依赖项时,我可以按<!>“去执行<!>”;我的IDE中的关键是已知的实现列表。在大多数情况下,只有一个实现,我直接进入课堂。不能简单得多,而且我总是知道正好正在使用什么实现(我声称相反的情况更接近于xml布线的真相 - 有趣的是你的视角如何变化!)

现在你可以说它只是一个非常简单的层,但是我们添加到系统中的每一层抽象都增加了的复杂性。我真的不认为xml曾经为我使用的任何系统增加了任何实际价值。

我曾经使用过的大多数系统只有生产运行时环境的一个配置。可能还有其他配置用于测试等。

我认为完全自动装配是春天的红宝石:它包含了大多数用例遵循的正常和常见使用模式的概念。使用XML配置,您允许许多一致/不一致的配置使用,可能/可能不是。我已经看到了很多xml配置过多的不一致 - 它是否与代码一起被重构?没想到。那些变化是有原因的吗?通常不会。

我们很难在配置中使用限定符,并找到了解决这些问题的其他方法。这是一个明确的<!>“缺点<!>”;我们遇到:我们稍微改变了编码方式,使其与自动装配更加平滑:客户存储库不再实现通用Repository<Customer>接口,但我们创建了扩展CustomerRepository的接口@Component。在子类化方面,有时候还有一两招。但它通常只是指向我们更强的打字方向,我发现这几乎总是一个更好的解决方案。

但是,是的,你正在追求一种主要是春天的特定风格的DI。我们甚至不再为依赖关系制作公共setter(所以你可以说我们在封装/信息隐藏部门中是+1)我们的系统中仍然有一些xml,但xml基本上只有 包含anomalies。完全自动装配与xml很好地集成。

我们现在唯一需要的是将java.util.concurrent,<=>和其他内容包含在JSR中(如 JSR-250 ),所以我们不必配上spring。这就是过去发生的事情(<=>东西浮现在脑海中),所以如果再次发生这种情况我不会感到完全惊讶。

其他提示

对我来说,这是我喜欢/不喜欢 Spring 和自动装配的地方。

优点:

  • 自动装配摆脱了讨厌的 XML 配置。
  • 使用注释更加容易,它允许您直接使用字段、setter 方法或构造函数进行注入。还允许您注释和“限定”注入的 bean。

缺点:

  • 使用自动装配和注释使您依赖于 Spring 库,与 XML 配置一样,您可以选择使用或不使用 Spring 运行。正如您所说,您会与 DI 框架联系在一起。
  • 同时我喜欢能够“限定”bean,对我来说这使得代码非常混乱。如果您需要在多个位置注入相同的 bean,我已经看到相同的字符串名称到处重复。对我来说,这似乎有可能出错。

我开始在工作中几乎完全使用自动装配,因为无论如何我们都非常依赖 Spring 集成,以至于依赖性问题没有实际意义。我参与了一个 Spring MVC 项目,该项目广泛使用自动装配,但有点难以理解。

我认为自动装配是一种后天习得的习惯,一旦你习惯了它,你就会意识到它是多么强大、简单,而且比 XML 配置更容易使用。

我们正在大项目中从@Autowire切换回XML配置。问题是自举性能非常低。自动装配扫描程序从自动装配搜索类路径加载所有类,因此,在Spring初始化期间急切地加载了许多类。

关于切换环境的讨论很少。我参与其中的大多数项目都是根据我们正在处理的环境注入依赖项的真正问题。使用xml配置,使用Spring EL非常简单,我不知道任何带有注释的好解决方案。我刚想出一个:

    @Value("#{${env} == "production" ? realService : dummyService}")
    private SomeService service;

它应该可行,但不是一个很好的解决方案imho。

我已切换到@Autowire。在一个小项目以外的任何其他项目上维护XML配置成为一项任务本身,理解很快就会降级。

IntelliJ为Spring注释提供了良好的(非完美的)支持。

我对这个问题的看法是,xml配置降低了代码的清晰度,特别是在大型系统中。

像@Component这样的注释会让事情变得更糟。它引导开发人员使对象变得可变,因为在需要提供默认构造函数的情况下,依赖关系不再是最终的。依赖关系需要通过公共设置器注入,或者通过@Autowired不受控制。 [更糟糕的依赖注入受到实例化其依赖关系的类的影响,我仍然在新编写的代码中看到这一点!]。通过不受控制,我的意思是,在大型系统中,当该类型的多个实现(或子代)可用时,它将更多地涉及了解哪些实现是@Autowired,这使得调查错误的复杂性变得更加困难。这也意味着,据说你有一个测试环境的配置文件和另一个用于生产的配置文件,你的生产错误只会在它最大的时候发生 - 在生产中,而不是能够发现测试环境中的错误,甚至更好,在编译时间!

我坚持使用声明我的配置类的中间地带(使用@Configuration的基于java的Spring配置)

我在配置类中明确声明了所有bean。我只在配置类中使用@Autowired,目的是限制对配置类的依赖性

@Configuration驻留在特定的包中,这是弹簧扫描运行的唯一位置。 (这大大加快了大型项目的开始时间)

我努力使我的所有类都不可变,特别是数据对象,JPA,Hibernate和Spring,以及许多序列化库似乎都会破坏它。我避开任何迫使我提供setter的东西,或从我的财产声明中删除final关键字。

减少在创建对象后更改对象的可能性,大大减少了大型系统中的错误,并减少了在存在错误时查找错误的时间。

它似乎也迫使开发人员更好地设计系统不同部分之间的交互。问题和错误变得越来越多,编译错误减少了浪费时间并提高了工作效率。

以下是一些经验
优点

  • 使配置更容易,因为我们可以只使用@Autowire注释
  • 不想使用setter方法,这样类会更干净

缺点

  • 即使我们使用 DI,也与 xml 文件紧密耦合
  • 很难找到实现(但是如果你使用像 intellij 这样的好的IDE,那么你肯定可以摆脱这个)

根据我的个人经验,除了在测试用例中,我并没有太多使用 @AutoWire 注释。

我真的很喜欢用注释来编写,而不是 XML。根据Spring手册和最新版本,XML和Annotation达到了相同的结果。

这是我的清单

专业人士:

  • 从 xml 中删除无用的行
  • 简化代码调试:当您打开课程时,您可以阅读课程中的内容
  • 开发速度更快,400行以上XML的项目可读吗?

缺点:

  • 不是标准的Java实现,但是你可以切换到使用@Inject,它是一个Java标准Api,所以bean仍然是Pojo
  • 你不能简单地在任何地方使用数据库连接等,但这只是一个意见,我更喜欢有一个地方可以读取所有配置。

为了我的理解@Autowired是最好用的,同时引用接口引用并使用它的覆盖功能,但我发现它的问题是它有时在运行时被赋值为null。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top