依赖注入,Scala和Spring

时间:2010-08-11 23:28:59

标签: spring scala dependency-injection

我非常喜欢DI和松散耦合系统的概念。但是,我发现Spring中的工具最多缺乏。例如,很难进行“重构”,例如更改Spring中声明的bean的名称。我是Spring的新手,所以我会遗漏一些东西。没有编制时间检查等。

我的问题是为什么我们要使用XML来存储配置? IMO,Spring(IoC部分)的整个想法是强制某些创造模式。在四人一组模式的世界中,设计模式是信息性的。另一方面,Spring(和其他DI)提供了一种非常规定的方式,即如何将应用程序与各个组件连接起来。

我已将Scala放入标题以及我正在学习它。你们怎么想创建一个领域语言(比如演员库)来依赖摄取。在Scala中编写实际的注入代码,您将获得随附的所有好东西和工具。虽然应用程序开发人员可能会绕过您的框架,但我认为标准相对容易,例如主网站/应用程序只会加载某些模式的组件。

7 个答案:

答案 0 :(得分:4)

有一篇关于将Scala与Spring和Hibernate here一起使用的好文章。

关于您的问题:您实际上可以使用注释。它有一些优点。反过来,XML很好,因为你不需要重新编译包含注射配置的文件。

答案 1 :(得分:4)

如果Scala 需要 DI,则存在争议。有几种方法可以“自己动手”,但通常这种简单的设置就足够了:

//the class that needs injection
abstract class Foo {
  val injectMe:String
  def hello = println("Hello " + injectMe)
}

//The "binding module"
trait Binder {
  def createFooInstance:Foo
}

object BinderImpl extends Binder {
  trait FooInjector {
    val injectMe = "DI!"   
  }

  def createFooInstance:Foo = new Foo with FooInjector
}

//The client
val binder:Binder = getSomehowTheRightBinderImpl  //one way would be a ServiceLoader
val foo = binder.createFooInstance
foo.hello
//--> Hello DI!

对于其他版本,请查看here例如。

答案 2 :(得分:2)

  

我非常喜欢DI的概念   耦合系统,很多。但是,我   在Spring找到工具缺乏   最好。例如,这很难做到   “重构”,例如更改名称   在Spring中声明的bean。我是新来的   春天,所以我会失踪   一些东西。没有编译时间   检查等。

您需要一个更智能的IDE。 JetBrains的IntelliJ允许重构,重命名等,并且完全了解Spring配置和类。

  

我的问题是我们为什么要使用   XML存储配置?

为什么不呢?你必须把它放在某个地方。现在您可以选择:XML或注释。

  

IMO,   Spring(IoC部分)的整个想法是   强迫某些创作模式。   在四人联合的世界中,   设计模式是有益的。

ApplicationContext只不过是一个大对象工厂/构建器。这是一个GoF模式。

  

Spring(和其他DI)在另一方面   手,提供非常规定的方式如何   应该连接一个应用程序   个别组件。

GoF更具说明性:您必须将其构建为对象或将其外部化为配置。 Spring将其外化。

  

我也把Scala放在标题中   因为我正在学习它。你好吗?   想创建一种域语言   (类似于演员库)   依赖摄取。

你必须指的是“注射”。

  

写作   Scala本身的实际注入代码,   你得到了所有的好东西和工具   附带它。

不要看到春天给我的东西会超过春天给我的东西。

  

虽然   应用程序开发人员也可能   我想,绕过你的框架   标准相对容易,比如说   作为主要的网站/应用程序将只   加载某种模式的组件。

抱歉,我不是在买你的想法。我宁愿用Spring。

但是没有理由不尝试它,看看你是否能比Spring更成功。让我们知道你是怎么做的。

答案 3 :(得分:2)

java中有 DI 的不同方法,并非所有方法都必须基于xml。

<强>弹簧

Spring 提供了一个完整的容器实现,并与许多服务(事务,jndi,持久性,数据源,mvc,调度......等)集成,实际上可以使用java注释更好地定义。

它的受欢迎程度源于平台集成的服务数量,而不是 DI (许多人将其用作 Java EE 的替代品,实际上是在春天之后路径从5版本开始。)

XML是 spring 的最初选择,因为它是框架实现时的事实上的java配置标准。注释是目前流行的选择。

作为个人而言,概念上我不是基于注释的DI 的忠实粉丝,对我而言,它创建了配置和代码的紧密耦合,从而挫败了 DI

围绕该支持备选配置声明还有其他 DI 实现:AFAIK Google Guice也是允许编程配置的其中之一。


DI和Scala

scala中有 DI 的替代解决方案,除了使用已知的java框架(据我所知,它集成得相当好)。

对我而言,保持熟悉的java方法最有趣的是subcut

它在谷歌guice和scala语言的特定设计所允许的最着名的DI模式之一之间取得了很好的平衡:Cake Pattern。您可以使用google search找到有关此模式的许多博文和视频。

scala中提供的另一个解决方案是使用Reader Monad,这已经是Haskell中已建立的动态配置模式,并在此video from NE Scala Symposium 2012和此{{3}中得到了相当好的解释。和相关的video

后一种选择伴随着警告,即它对Monad概念和scala的概念有着相当的熟悉程度,并且常常引起围绕其概念复杂性和实际用途的一些争论。与 scala-debate ML 相关的slides对于更好地掌握主题非常有用。

答案 4 :(得分:0)

我无法评论scala,但DI有助于强制松散耦合。它使重构大型应用程序变得更容易。如果您不喜欢某个组件,只需将其换掉即可。需要针对特定​​环境的其他实现,只需插入新组件即可。

答案 5 :(得分:0)

我同意!对我而言,大多数人使用Spring的方式都是一个温和的地狱版本。

当您查看标准的Springified代码时,到处都有接口,并且您从未真正知道用于实现接口的类。您必须查看一些出色的配置才能找到答案。易读=不。为了使这个代码易于浏览,你需要一个非常先进的IDE,比如Intelly J.

我们是如何在这个混乱中结束的?我责怪自动化单元测试!如果要将mocks连接到每个类,则不能具有依赖关系。如果不是单元测试,我们很可能在没有松散耦合的情况下做到这一点,因为我们不希望客户在我们的Jars中不知不觉地更换单个类。

在Scala中,您可以使用模式,例如“Cake Patten”来实现没有框架的DI。您也可以使用结构类型来执行此操作。与原始代码相比,结果仍然很混乱。

我个人认为应该考虑对模块进行自动化测试而不是类来逃避这种混乱,并使用DI来解耦整个模块。根据定义,该策略不是单元测试。我认为大多数逻辑都在于类之间的实际连接,因此恕我直言的模块测试比单元测试更有益。

答案 6 :(得分:0)

我不能同意XML在Java和Spring中存在问题: 我广泛使用Spring和Java而没有太多XML,因为大多数配置都是用注释完成的(类型和名称是强大的契约) - 它看起来非常好。仅在10%的情况下我使用XML,因为在XML中比使用工厂/新类/注释的代码特殊解决方案更容易。这种方法的灵感来自Guice,而Spring从3.0实现了它作为JSR-330(但即使我使用Spring 2.5配置弹簧工厂配置了JSR-330注释而不是默认的特定于Spring的@Autowired)。

可能scala可以为DI风格的开发提供更好的语法,我现在正在看它(尖头蛋糕模式)。