Java Spring @Autowired 用法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/633158/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 17:11:24  来源:igfitidea点击:

Spring @Autowired usage

javaspringautowired

提问by Andy White

What are the pros and cons of using @Autowiredin a class that will be wired up by Spring?

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

Just to clarify, I'm talking specifically about the @Autowiredannotation, not auto-wiring in XML.

为了澄清起见,我专门讨论@Autowired注释,而不是 XML 中的自动连接。

I probably just don't understand it, but to me it almost seems like an anti-pattern - your classes start to become aware that they are tied to a DI framework, rather than just being POJOs. Maybe I'm a glutton for punishment, but I like having the external XML config for beans, and I like to have explicit wirings, so I know exactly what is wired where.

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

采纳答案by krosenvold

For a long time I believed that there was a value in having a "centralized, declarative, configuration" like the xml files we all used to use. Then I realized that most of the stuff in the files wasn't configuration- it was never changed anywhere after development, ever. Then I realized that "centralized" only has value in quite small systems - only in small systems will you ever be able to grok a configuration file as a whole. And what is really the value of understanding the wiring as a whole, when the same "wirings" are mostly duplicated by dependencies in the code? So the only thing I've kept is meta-data (annotations), which is still kind-of declarative. These neverchange at runtime and they're never"configuration" data that someone will change on the fly - so I think keeping it in the code is nice.

很长一段时间以来,我相信拥有像我们过去都使用的 xml 文件一样的“集中式、声明式、配置”是有价值的。然后我意识到文件中的大部分内容都不是配置——它在开发之后从未改变过。然后我意识到“集中式”只在非常小的系统中有价值——只有在小系统中,你才能将配置文件作为一个整体来理解。当相同的“布线”大多由代码中的依赖项重复时,从整体上理解布线的真正价值是什么?所以我唯一保留的是元数据(注释),它仍然是一种声明性的。这些在运行时永远不会改变,他们永远不会有人会即时更改的“配置”数据 - 所以我认为将其保留在代码中很好。

I use full auto-wiring as much as I can. I love it. I won't go back to old-style spring unless threatened at gun-point. My reasons for preferring fully @Autowiredhave changed over time.

我尽可能多地使用全自动接线。我喜欢它。除非受到枪口威胁,否则我不会回到旧式春天。@Autowired随着时间的推移,我更喜欢完全的原因已经改变。

Right now I think the most important reason for using autowiring is that there's one less abstraction in your system to keep track of. The "bean name" is effectively gone. It turns out the bean name only exists because of xml. So a full layer of abstract indirections (where you would wire bean-name "foo" into bean "bar") is gone. Now I wire the "Foo" interface into my bean directly, and implementation is chosen by run-time profile. This allows me to work with codewhen tracing dependencies and implementations. When I see an autowired dependency in my code I can just press the "go to implementation" key in my IDE and up comes the list of known implementations. In most cases there's just one implementation and I'm straight into the class. Can't be much simpler than that, and I always know exactlywhat implementation is being used (I claim that the opposite is closer to the truth with xml wiring - funny how your perspective changes!)

现在我认为使用自动装配的最重要原因是您的系统中需要跟踪的抽象减少了。“bean name”实际上已经消失了。事实证明,bean 名称仅存在于 xml 中。因此,完整的抽象间接层(您将 bean-name “foo” 连接到 bean “bar” 的地方)已经消失了。现在我将“Foo”接口直接连接到我的 bean 中,并由运行时配置文件选择实现。这允许我在跟踪依赖项和实现时使用代码。当我在我的代码中看到自动装配的依赖项时,我只需在我的 IDE 中按“转到实现”键,就会出现已知实现的列表。在大多数情况下,只有一个实现,我直接进入课堂。能'正在使用什么实现(我声称相反的情况更接近于 xml 布线的真相 - 有趣的是你的观点是如何变化的!)

Now you could say that it's just a very simple layer, but each layer of abstraction that we add to our systems increasecomplexity. I really don't think the xml ever added any real value to any system I've worked with.

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

Most systems I've ever work with only have oneconfiguration of the production runtime environment. There may be other configurations for test and so on.

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

I'd say that full autowiring is the ruby-on-rails of spring: It embraces the notion that there's a normal and common usage pattern that most use cases follow. With XML configuration you permita lot of consistent/inconsistent configuration usage that may/may not be intended. I've seen so much xml configuration go overboard with inconsistencies - does it get refactored together with the code ? Thought not. Are those variations there for a reason? Usually not.

我会说完全自动装配是 spring 的 ruby​​-on-rails:它包含了大多数用例遵循的正常和常见使用模式的概念。使用 XML 配置,您可以允许许多可能/可能不打算使用的一致/不一致的配置使用。我已经看到太多 xml 配置因不一致而过火 - 它是否与代码一起重构?没想到。这些变化是有原因的吗?通常不会。

We hardly use qualifiers in our configuration, and found other ways to solve these situations. This is a clear "disadvantage" we encounter: We've slightly changed the way we code to make it interact smoother with autowiring: A customer repository no longer implements the generic Repository<Customer>interface but we make an interface CustomerRepositorythat extends Repository<Customer>. Sometimes there's also a trick or two when it comes to subclassing. But it usually just points us in the direction of stronger typing, which I find is almost always a better solution.

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

But yes, you're tying to a particular style of DI that mostly spring does. We don't even make public setters for dependencies any more (So you could argue that we're +1 in the encapsulation/information hiding department) We still have some xml in our system, but the xml basically onlycontains the anomalies. Full autowiring integrates nicely with xml.

但是,是的,您正在使用一种特定的 DI 风格,这种风格主要是 spring 的。我们甚至不再为依赖项创建公共设置器(所以你可以争辩说我们在封装/信息隐藏部门+1)我们的系统中仍然有一些 xml,但 xml 基本上包含异常。完全自动装配与 xml 很好地集成。

The only thing we need now is for the @Component, @Autowiredand the rest to be included in a JSR (like JSR-250), so we don't have to tie in with spring. This is the way things have been happening in the past (the java.util.concurrentstuff springs to mind), so I wouldn't be entirely surprised if this happened again.

我们现在唯一需要的是将@Component@Autowired其余部分包含在 JSR(如JSR-250)中,因此我们不必与 spring 联系起来。这就是过去发生的事情的方式(这些java.util.concurrent事情浮现在脑海中),所以如果这种情况再次发生,我不会完全感到惊讶。

回答by Jared Knipp

For me here is what I like/dislike about Spring and auto-wiring.

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

Pros:

优点:

  • Auto-wiring gets rid of nasty XML configuration.
  • Much easier to use annotations which allows you to inject directly using fields, setter methods, or constructors. Also allows you to annotate and 'qualify' your injected beans.
  • 自动接线摆脱了讨厌的 XML 配置。
  • 更容易使用注解,它允许您使用字段、setter 方法或构造函数直接注入。还允许您对注入的 bean 进行注释和“限定”。

Cons:

缺点:

  • Using auto-wiring and annotations makes you dependent on Spring libraries where as with XML configuration you could chose to run with or without Spring. Like you said, you become tied to a DI framework.
  • At the same time I like being able to 'qualify' beans, to me this makes the code really messy. If you need to inject the same bean in multiple places, I've seen the same string name repeated all over. To me this seems to have the potential for errors.
  • 使用自动装配和注释使您依赖于 Spring 库,而对于 XML 配置,您可以选择使用或不使用 Spring 运行。就像你说的那样,你被依赖于一个 DI 框架。
  • 同时我喜欢能够“限定”bean,对我来说这使得代码非常混乱。如果您需要在多个地方注入相同的 bean,我已经看到相同的字符串名称到处重复。对我来说,这似乎有可能出错。

I've started using auto-wiring almost exclusively at work because we depend so much on Spring integration anyway that the dependency issue is moot. I worked on a Spring MVC project that used auto-wiring extensively and was a little hard to wrap my head around.

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

I think auto-wiring is an acquired taste, once you get used to it you realize how powerful, easy, and much less of a headache it is to work with than the XML configuration.

我认为自动装配是一种后天习得的品味,一旦您习惯了它,您就会意识到与 XML 配置相比,它是多么强大、简单,而且使用起来也不那么令人头疼。

回答by Paul McKenzie

I have switched to @Autowire. Maintaining the XML configuration on anything other than a small project became a task in it's own right and comprehension quickly degraded.

我已经切换到@Autowire。除了小项目之外,在任何其他项目上维护 XML 配置本身就成为一项任务,并且理解能力迅速下降。

IntelliJ provides good (not perfect) support for Spring annotations.

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

回答by Masterhard

We are switching from @Autowire back to XML configuration in our big project. The problem is very low bootstrap performance. Autowiring scanner loads all classes from autowiring search classpath, so, lots of classes are loaded eagerly during Spring initialization.

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

回答by Charbel

My take on this subject is that, xml configuration reduce the clarity of the code, especially in large systems.

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

Annotations like @Component makes things even worse. It steers developers to make objects mutable, as dependencies can't be made final anymore, given that default constructors need to be provided. Dependencies need to be either injected through public setter, or uncontrolled through @Autowired. [even worse dependency injection is compromised with classes that instantiate their dependencies, I still see this in newly written code!]. By uncontrolled I mean, in large systems, when multiple implementations (or children) of the type are available, it gets much more involved to understand which of the implementations was @Autowired, a complexity that makes investigating bugs much harder. It also means that, supposedly you have a profile for test environment and another for production, your production bugs will only happen when it hurts most - in production, rather than being able to spot the bugs in the test environment, or even better, at compile time!

像@Component 这样的注释让事情变得更糟。它引导开发人员使对象可变,因为依赖项不再是最终的,因为需要提供默认构造函数。依赖项要么通过公共 setter 注入,要么通过 @Autowired 不受控制。[更糟糕的依赖注入被实例化其依赖项的类所破坏,我仍然在新编写的代码中看到这一点!]。不受控制的意思是,在大型系统中,当该类型的多个实现(或子项)可用时,了解哪些实现是 @Autowired 会变得更加复杂,这种复杂性使得调查错误变得更加困难。这也意味着,假设您有一个用于测试环境的配置文件和另一个用于生产环境的配置文件,

I stick to the middle ground where I declare my configuration class(es), (java based Spring configuration using @Configuration)

我坚持中间立场,在那里我声明我的配置类,(使用@Configuration 的基于 java 的 Spring 配置)

I declare all my beans explicitly in the configuration class(es). I only use @Autowired in the configuration class(es), the purpose is to limit dependency on Spring to the configuration class(es)

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

The @Configuration reside in a specific package, that's the only place where the spring scan runs. (That speeds up start time substantially in large projects)

@Configuration 驻留在一个特定的包中,这是 spring 扫描运行的唯一地方。(这大大加快了大型项目的启动时间)

I strive to make all my classes immutable, especially the data object, JPA, Hibernate and Spring, as well as many serialization libraries seem to undermine this. I steer away from anything that forces me to provide setters, or remove the final keyword from my property declaration.

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

Reducing the possibilities of changing objects after they're created, reduces substantially the bugs in large system as well as reduces the time to find a bug when one exists.

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

It also seems that it forces developer to better design the interaction between the different parts of the system. Problems and bugs become more and more compilation errors, that reduces wasted time and improve productivity.

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

回答by Rajith Delantha

Here are some of experience
Pros

这里有一些经验的
优点

  • Makes easier to configure because we can just use @Autowire annotation
  • Don't want to use setter methods , so class will be more clean
  • 更容易配置,因为我们可以只使用@Autowire 注释
  • 不想使用setter方法,所以类会更干净

Cons

缺点

  • Tightly couple to xml file even though we are using DI
  • Hard to find implementation (But if you your using good ides like intellij sure you can get rid of this)
  • 即使我们使用 DI 也紧密耦合到 xml 文件
  • 很难找到实现(但如果你使用像 intellij 这样的好想法,你肯定可以摆脱这个)

As of my personal experiences I didn't use @AutoWire annotation that much but in test cases.

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

回答by BTakacs

There has been very little discussion about switching environments. Most projects I've worked on it was a real issue to inject dependencies depending on the environment we are working on. With xml config it's pretty straightforward with Spring EL, and I am not aware of any nice solution with annotations. I've just figured out one:

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

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

It should be working, but not a nice solution imho.

它应该工作,但不是一个很好的解决方案恕我直言。

回答by Luca Preziati

I really love write with annotations, instead of XML. According to the Spring manual and the last versions, XML and Annotation achieved the same result.

我真的很喜欢用注释而不是 XML 来写。根据 Spring 手册和上一版本,XML 和 Annotation 实现了相同的结果。

This is my list

这是我的清单

Pro:

亲:

  • Remove useless line from xml
  • Simplify the debugging the code: when you open a class, you can read what you have in the class
  • More fast developping, a project with 400 or more line of XML is readable?
  • 从 xml 中删除无用的行
  • 简化调试代码:当你打开一个类时,你可以阅读你在类中的内容
  • 开发速度更快,400多行XML的项目可读吗?

Cons:

缺点:

  • Is not standard Java implementation, but you can switch to use @Inject, which is a Java Standard Api, so the bean remain a Pojo
  • You cannot simply use everywhere, db connection e so on, but it's only an opinion, i prefer have a place where read all configuration.
  • 不是标准的 Java 实现,但您可以切换到使用 @Inject,这是一个 Java 标准 Api,因此 bean 仍然是一个 Pojo
  • 您不能简单地在任何地方使用,db connection e 等等,但这只是一种意见,我更喜欢有一个地方可以阅读所有配置。

回答by Shubham kapoor

For my understanding @Autowired is the best to use while refer to interface reference and use its override funtions, but I only find issue with this is that it sometimes assigned to null at runtime.

根据我的理解,@Autowired 最好在引用接口引用并使用其覆盖函数时使用,但我只发现它的问题在于它有时在运行时分配给 null。