首页 文章

Spring @Autowired用法

提问于
浏览
205

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

只是为了澄清,我正在具体谈论 @Autowired 注释,而不是XML中的自动连线 .

我可能只是不理解它,但对我来说它几乎看起来像一个反模式 - 你的类开始意识到它们与DI框架相关联,而不仅仅是POJO . 也许我是一个贪婪的惩罚,但我喜欢有bean的外部XML配置,我喜欢有明确的布线,所以我确切知道什么是连线在哪里 .

9 回答

  • 1

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

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

  • 3

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

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

    我坚持在中间地方,我声明我的配置类,(使用@Configuration的基于Java的Spring配置)

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

    @Configuration位于特定包中,这是 spring 扫描运行的唯一位置 . (这大大加快了大型项目的开始时间)

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

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

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

  • 26

    很长一段时间以来,我一直认为像我们以前用过的xml文件一样有一个 Value . 然后我意识到文件中的大多数东西都不是配置 - 它在开发之后从未改变过 . 然后我意识到"centralized"仅在非常小的系统中具有 Value - 只有在小型系统中,您才能够整体地查看配置文件 . 当相同的"wirings"大部分被代码中的依赖项复制时,整体理解布线的真正 Value 是什么?所以我唯一保留的是元数据(注释),这仍然是一种声明式的 . 这些在运行时永远不会改变,并且它们永远不会有人会随时改变数据 - 因此我认为将其保留在代码中是很好的 .

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

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

    现在你可以说它只是一个非常简单的层,但是我们添加到系统中的每一层抽象都会增加复杂性 . 我真的不喜欢和他们一起工作过 .

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

    我'd say that full autowiring is the ruby-on-rails of spring: It embraces the notion that there'是大多数用例遵循的正常和常见用法模式 . 使用XML配置,您可以允许大量一致/不一致的配置使用,这可能是/可能不是 . 我已经看到了很多xml配置过多的不一致 - 它是否与代码一起被重构?没想到 . 那些变化是有原因的吗?通常不是 .

    我们在配置中几乎不使用限定符,并找到了解决这些情况的其他方法 . 这是一个明确的"disadvantage"我们遇到:我们稍微改变了我们编码的方式,使其与自动装配交互更顺畅:客户存储库不再实现通用 Repository<Customer> 接口,但我们创建了扩展 Repository<Customer> 的接口 CustomerRepository . 在子类化方面,有时候还有一两招 . 但它通常只是指向我们更强的打字方向,我发现这几乎总是一个更好的解决方案 .

    但是,是的,你甚至不再为依赖关系做公共设置者了(所以你可以说我们在封装/信息隐藏部门是1)我们的系统中仍然有一些xml,但xml基本上只包含异常 . 完全自动装配与xml完美集成 .

    我们现在唯一需要的是 @Component@Autowired ,其余的都包含在JSR中(如JSR-250),所以我们不必配合spring . 这就是过去发生的事情(脑海中出现的情况),所以如果再次发生这种情况,我不会感到完全惊讶 .

  • 6

    对我来说,这是我喜欢/不喜欢Spring和自动接线的 .

    优点:

    • 自动连线摆脱了令人讨厌的XML组态 .

    • 更容易使用注释,允许您使用字段,setter方法或构造函数直接注入 . 还允许您注释注入的bean和'qualify' .

    缺点:

    • 使用自动连接和注释使您依赖于Spring库,您可以选择在有或没有Spring的情况下运行XML配置 . 就像你说的那样,你与DI框架联系在一起 .

    • 与此同时,我喜欢能够使用_1328330_ bean,对我来说,这会使代码变得非常混乱 . 如果你需要在多个地方注入相同的bean,我已经看到了遍及重复的相同字符串名称 . 对我来说,这似乎有可能出错 .

    我几乎完全在工作中开始使用自动连接,因为我们非常依赖Spring集成,因为依赖性问题没有实际意义 . 我参与了一个Spring MVC项目,该项目广泛使用自动布线,并且有点难以绕过我的脑袋 .

    我认为自动接线是一种后天的品味,一旦你习惯它,你会发现它比XML配置更有效,更轻松,更难以使用 .

  • 4

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

  • 1

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

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

    它应该工作,但不是一个很好的解决方案imho .

  • 246

    以下是一些经验
    Pros

    • 使配置更容易,因为我们可以使用@Autowire注释

    • 不想使用setter方法,所以上课会更干净

    Cons

    • 即使我们正在使用DI,也会紧紧联系到xml文件

    • 很难找到实现(但如果你使用像intellij这样的好想法,你肯定可以摆脱这个)

    根据我的个人经验,我没有使用@AutoWire注释,但在测试用例中 .

  • 14

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

    这是我的清单

    优点:

    • 从xml中删除无用的行

    • 简化代码调试:打开课程时,您可以阅读课程中的内容

    • 更快速的开发,具有400或更多XML系列的项目是否可读?

    缺点:

    • 不是标准的Java实现,但你可以切换到使用@Inject,这是一个Java Standard Api,所以bean仍然是一个Pojo

    • 你不能简单地在任何地方使用,数据库连接等等,但它只是一个意见,我更喜欢有一个读取所有配置的地方 .

  • 0

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

相关问题