在Spring将要连接的类中使用@Autowired的优缺点是什么?
为了澄清一下,我特别讨论的是@Autowired注释,而不是XML中的自动连接。
我可能只是不理解它,但对我来说,这似乎是一种反模式——您的类开始意识到它们被绑定到DI框架上,而不仅仅是pojo。也许我是一个贪吃惩罚的人,但是我喜欢为bean使用外部XML配置,而且我喜欢显式连接,这样我就确切地知道在哪里连接了什么。
在Spring将要连接的类中使用@Autowired的优缺点是什么?
为了澄清一下,我特别讨论的是@Autowired注释,而不是XML中的自动连接。
我可能只是不理解它,但对我来说,这似乎是一种反模式——您的类开始意识到它们被绑定到DI框架上,而不仅仅是pojo。也许我是一个贪吃惩罚的人,但是我喜欢为bean使用外部XML配置,而且我喜欢显式连接,这样我就确切地知道在哪里连接了什么。
当前回答
根据我的理解,@Autowired是最好的使用,同时参考接口引用和使用它的覆盖函数,但我只发现问题是,它有时在运行时被分配为null。
其他回答
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 never change 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.
我尽可能多地使用全自动布线。我很喜欢。除非有人用枪威胁我,否则我不会回到老式的春天。随着时间的推移,我完全喜欢@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 code when 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 exactly what implementation is being used (I claim that the opposite is closer to the truth with xml wiring - funny how your perspective changes!)
现在你可以说它只是一个非常简单的层,但是我们添加到系统中的每一个抽象层都会增加复杂性。我真的不认为xml为我使用过的任何系统增加了任何真正的价值。
我使用过的大多数系统只有生产运行时环境的一个配置。可能会有其他配置用于测试等等。
我想说,完全自动装配是弹簧上的红宝石:它包含了大多数用例遵循的正常和常见的使用模式的概念。使用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 CustomerRepository that 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.
但是,是的,您正在绑定到一种特定的DI风格,而spring主要是这样做的。我们甚至不再为依赖项设置公共设置(所以你可能会认为我们在封装/信息隐藏部门中是+1)我们的系统中仍然有一些xml,但xml基本上只包含异常。完全自动装配很好地集成了xml。
现在我们唯一需要做的就是将@Component、@Autowired和其他组件包含在JSR(如JSR-250)中,这样我们就不必与spring绑定。这是过去发生的事情的方式(想到java.util.concurrent的东西),所以如果再次发生这种情况,我不会完全感到惊讶。
在我们的大项目中,我们正在从@Autowire切换回XML配置。问题是bootstrap性能非常低。自动装配扫描器从自动装配搜索类路径加载所有类,因此,很多类在Spring初始化时被急切地加载。
我对这个主题的看法是,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!
我坚持中间立场,在那里我声明我的配置类(es),(基于java的Spring配置使用@Configuration)
我在配置类中显式地声明了所有bean。我只在配置类中使用@Autowired,目的是限制Spring对配置类的依赖。
@Configuration位于一个特定的包中,这是spring扫描运行的唯一位置。(这大大加快了大型项目的启动时间)
我努力使我的所有类都是不可变的,尤其是数据对象、JPA、Hibernate和Spring,以及许多序列化库似乎都破坏了这一点。我避免任何强迫我提供setter或从属性声明中删除最后一个关键字的操作。
减少对象创建后更改的可能性,大大减少了大型系统中的bug,并减少了在存在bug时查找bug的时间。
它似乎还迫使开发人员更好地设计系统不同部分之间的交互。问题和bug变成越来越多的编译错误,这减少了浪费的时间,提高了工作效率。
我已经切换到@Autowire。在小型项目以外的任何项目上维护XML配置都成为了一项独立的任务,而且理解能力很快就下降了。
IntelliJ为Spring注释提供了很好的(不是完美的)支持。
关于切换环境的讨论很少。在我参与过的大多数项目中,根据我们所工作的环境注入依赖项是一个真正的问题。使用Spring EL的xml配置非常简单,而且我不知道任何带有注释的好解决方案。我刚刚发现了一个问题:
@Value("#{${env} == "production" ? realService : dummyService}")
private SomeService service;
它应该会起作用,但不是一个很好的解决方案。