2015-01-26 51 views
0

我喜欢将Spring添加到我的Scala项目中以用于教育目的。但我不明白Spring Scala的优势在于解耦组件。如何使用spring scala来解耦?

我创建了一个简单的配置:

import org.springframework.scala.context.function.FunctionalConfiguration 

class Configuration extends FunctionalConfiguration { 
    bean() { 
    new Service() 
    } 
} 

和一个简单的服务:

class Service { 
    def method = "Bonjour tout le monde!" 
} 

,然后一个应用程序,它同时使用:

import org.springframework.scala.context.function.FunctionalConfigApplicationContext 

object Application extends App { 
    implicit val context = FunctionalConfigApplicationContext(classOf[Configuration]) 

    val service = context.getBean(classOf[Service]) 
    println(service.method) 
} 

这只是我的解释和Spring Scala示例的实现。

我的应用程序仍然具有Service类的知识。我只能写:

val service = new Service() // instead of asking for a Bean which has classname Service 
println(service.method) 

具有相同的效果。

我错过了什么吗?

+0

我明白,并试图改变,如果bean(“sophisticatedService”){...}是可能的,并且用于文本定义bean,然后使用:context.getBean(“sophisticatedService”)。由于它现在被文本名称解耦。 – springScala 2015-01-26 22:06:05

+0

Spring对我来说真正解决的唯一问题是循环依赖。但后来我转向使用惰性vals(以避免null),并在构造函数中通过名称传入注入参数。所以,不要再使用Spring IoC了。有些人喜欢'@ Autowired'这个东西,但是你可以使用traits(在trait里面定义依赖关系,并将它混合到已经定义了这个依赖关系的上下文中) - 更多地使用google搜索'Cake pattern' – dk14 2015-01-27 01:01:10

+0

你可以使用spring你有服务和几个实现的接口,例如你的应用程序将依赖于UserRepository。您可以使用FileUserRepository实现,并且您的应用程序完全与该细节分离。稍后,您可以实现DatabaseUserRepository并切换实现,而无需触及代码,或者您可以使用mock进行测试,并仍然依赖于UserRepository保持不变的代码。 – chalimartines 2015-01-27 03:43:53

回答

0

这确实将您对Service的使用从实例化中分离出来。例如。如果将来Service更改取决于其他一些InnerService,或者由于某种原因而在构造函数中无法完成一些初始化,但在使用它之前需要在方法调用中发生(.connectToDatabase()等),或者如果您如果你对编程的接口,而不是实现,如

val service = context.getBean(classOf[Service]) 
println(service.method) 

:想用一个模拟测试,以取代Service,那么你就可以做到这一点没有改变这两行代码

trait IService { 
    def method: String 
} 
class Service extends IService... 

val service = context.getBean(classOf[IService]) 

那么你也做,就容易掉出Service对于不同的实现,虽然给出额外的代码行,我可能不会理会这样做,直到我其实有一个以上的实施。我不确定Spring是否有自己的重量(这是一个非常庞大而复杂的库),特别是在它的更简洁的构造函数语法的Scala中。但是,不管你是否使用Spring,都值得将你的依赖关系的构建与应用程序的“接线”与实际使用分开。使用Service的IMO类Foo应该明确地通过它的构造函数class Foo(service: Service)接受它,并将Service的构造/初始化保留为专用于该类的类/函数。