What are Dependency Injection & Spring Framework about?
Possible Duplicates:
What is dependency injection?
What exactly is Spring for?
我想知道什么是Spring框架?为什么要在Java企业开发中使用它?答案是"依赖注入框架"。好吧,在使用依赖注入框架时我们有什么优势?用setter值和/或构造函数参数描述类的想法对我来说似乎很奇怪。为什么会这样?因为我们可以在不重新编译项目的情况下更改属性?这就是我们所得到的吗?
那么,我们应该用beans.xml描述哪些对象呢?所有物体还是只有几个?
最简单的答案是受欢迎的
我们使用依赖注入(DI)来实现松耦合。选择任何特殊的DI容器都没有那么重要。
每次使用
这看起来像C(在爪哇相当):
1 2 3 4 5 6 7 | public class MyClass { public string GetMessage(int key) { return new MessageService().GetMessage(key) } } |
这意味着,如果您以后想使用不同的messageservice,则不能。
另一方面,如果您向类中注入一个接口并遵循Liskov子状态原则,那么您将能够独立地改变使用者和服务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class MyClass { private readonly IMessageService messageService; public MyClass(IMessageService messageService) { if(messageService == null) { throw new ArgumentNullException("messageService"); } this.messageService = messageService; } public string GetMessage(int key) { return this.messageService.GetMessage(key) } } |
虽然这看起来更复杂,但我们现在已经设法遵循了单一责任原则,确保每个合作者只做一件事,并且我们可以彼此独立地改变。
此外,我们现在可以在不改变类本身的情况下改变MyClass的行为,从而坚持开/闭原则。
重新配置被高估了。使用DI最重要的是可测试性。因为您的类不依赖于实现,而是依赖于抽象,所以您可以在单元测试中用mock/stub替换它们。
例子
没有DI:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class SaleAction{ private BillingService billingService; public SaleAction(){ billingService = new CreditCardService(); //dependency is hardcoded } public void pay(long amount){ //pre payment logic billingService.pay(amount); //post payment logic } } |
在这个例子中,假设您希望对
现在,DI的例子也一样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class SaleAction{ private BillingService billingService; public SaleAction(BillingService service){ billingService = service; //DI } public void pay(long amount){ //pre payment logic billingService.pay(amount); //post payment logic } } |
现在,
希望有帮助,这里还有马丁·福勒写的关于DI的文章,你可以在这里找到。
Spring已经变成了一个巨大的框架,如果您只是试图将您的头围绕在依赖注入上,那么这可能会让您感到困惑。谷歌Guice项目很小,只有纯Java的DI——没有XML,也没有额外的。还有一个很好的介绍视频来解释DI。http://code.google.com/p/google-guice/
这篇文章很好地解释了春天的想法。(作者Rod Johnson,Spring框架的创始人)
你已经有了一些很好的答案,我想回答几个具体的问题:
The idea of describing classes with setter values and/or constructor parameters seems strange to me. Why do that? Because we can change the properties without recompiling the project? Is that all what we gain?
< /块引用>
一开始看起来确实很奇怪,但问题是容器负责插入对象的依赖项,对象本身不负责。beans.xml中配置的对象的范围是由spring管理的,因此我们不必太担心没有正确的依赖关系而被实例化的事情(只要配置是正确的,就知道我会编写单元测试来检查spring配置是否在做我想做的事情)。
Then, what objects should we describe in beans.xml ? All objects or only a few ?
< /块引用>
bean.xml中描述的对象类型主要是组件——控制器、服务、数据访问对象,以及它们需要的事务管理器、休眠会话工厂、数据源等。域对象通常是从数据访问对象中检索或直接实例化的,因为除了其他域对象(或甚至比域类更独立的实用程序类)之外,它们不依赖其他任何对象。
我想我可以试着回答这个问题,尽管我不确定任何答案是否令人满意。
简单的答案是,Spring是技术的组合:
依赖注入,它使用好莱坞原则来帮助您保持接口和实现的独立性; 面向方面的编程,它将横切关注点隔离到可以声明地应用的模块中。AOP的"hello world"正在进行日志记录,但是它已经是一个春天了(例如事务、用于远程处理的动态代理、安全性等),您可以考虑使用servlet过滤器,这样您就有了这个想法; 用于帮助执行常见任务的库,如持久性(JDBC、Hibernate、iBatis、JDO、JPA等)、远程处理(RMI、HTTP、Web服务)、异步消息传递(消息驱动的POJO)、验证和绑定、Web MVC(Spring或Struts)、电子邮件、调度、安全性等实用程序。 但更深层的答案是,你得到了Rod Johnson作为JavaEE项目顾问的经验。他把为他工作的东西提炼成了21/Spring界面,现在你可以免费享受这些好处了。
Spring团队编写的代码设计、测试和遵循标准比我写的任何东西都更加严格。(想象一下JuergenHoellerBrowbeattrodJohnson,因为他的代码在签入之前不符合标准。)当我使用它们的框架代码时,我可以依靠它们,集中精力解决我的业务问题。我不会一次又一次地写样板代码。
对我来说,Spring更多的是一个架构模板,它可以作为创建Web应用程序的指南。有些人可能会说这是过度设计的,对于某些问题,他们是正确的,但是对于我经常遇到的问题,春天只是一张罚单。
至于子问题:
What advantages do we have when using dependency injection frameworks?
对象不必负责管理它们的依赖关系。Spring的应用程序上下文实际上只是一个来自GOF的大型工厂模式。它鼓励您设计一个接口,以便根据需要更改实现。您的持久性接口今天可能使用JDBC实现,明天休眠;您可能决定自动生成一个代理来管理其事务行为。如果将代码编码到接口,则不必更改任何客户机代码。
The idea of describing classes with setter values and/or constructor parameters seems strange to me. Why do that? Because we can change the properties without recompiling the
project? Is that all what we gain?奇怪?在代码中不使用属性或构造函数?之所以这么做,是因为大多数Java类都是这样编写的。Spring只使用这些机制作为向类提供依赖性的方法。
Then, what objects should we describe in beans.xml ? All objects or only a few ?
只有具有依赖性的bean。我仍然为特定方法的本地对象调用"new"。它们是在方法范围内创建、使用和垃圾收集的。这些不必由弹簧控制。
也许你不应该尝试进行"Java企业开发",而不需要了解一些基本的架构和设计问题。我建议你要么找一个愿意帮助你的有经验的同事,要么花更多的精力去读那些书,要么去学一门课程。
在任何情况下,你的问题都没有"简单的答案"。
这是BobLee提供的一个很好的视频,他正在研究Guice(Guice是一个类似Spring的依赖注入框架)。前10分钟左右是关于为什么Guice(或依赖注入)比其他(工厂)更好,所以这不仅仅是关于Guice。
意见:找出您试图用DI解决的问题,并采用最适合的框架。春天会给你的问题增加很多复杂性。
(马丁·福勒关于DI的第一篇文章之一。我认为DI这个词是在这篇文章中创造的。)
依赖项注入是一种解决缺少虚拟类的方法!
nbsp;
注意:如果您不知道什么是虚拟类,请参考"虚拟类,任何人?".