Reputation: 292
I have an application written partially in Java and Scala. In case of Scala code I want to use scala features to make dependency injection. In old Java code spring was used i.e. to inject services beans to wicket pages etc. In scala code I use selfless trait pattern to create services as described here: http://www.artima.com/scalazine/articles/selfless_trait_pattern.html
Dependency injection in scala is done currently using "Configuration" object which wires everything together:
scala> trait Friendly {
| def greet() { println("hi there") }
| }
defined trait Friendly
scala> object Friendly extends Friendly
defined module Friendly
scala> object ServiceConsumer {
| def myService: Friendly = myServiceInjected.getOrElse(throw new RuntimeException("dependency not injected"))
| var myServiceInjected: Option[Friendly] = None
| }
defined module ServiceConsumer
scala> class ServiceConsumer {
| def callService() {
| ServiceConsumer.myService.greet()
| }
| }
defined class ServiceConsumer
scala> object Configuration {
| def init() {
| ServiceConsumer.myServiceInjected = Some(Friendly)
| }
| }
defined module Configuration
scala> Configuration.init
scala> val c = new ServiceConsumer
c: ServiceConsumer = ServiceConsumer@292e2fba
scala> c.callService()
hi there
But how to use "Friendly" service from Java class? Should I still use Spring? How to publish Friendly service written in Scala as a Spring bean?
Upvotes: 0
Views: 965
Reputation: 4396
I'm using Spring DI absolutely hassle-free with Scala.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.mypackage"/>
</beans>
And then I specify the components I want with:
@Service
class MyService
and then access it through:
class OtherClass {
@Autowired
var myService:MyService = _
}
Upvotes: 0
Reputation: 49705
I'd create a factory method in Scala:
class MyService { def doSomething = ... }
object MyService {
def create: MyService = ...
}
Then use it from Java as a static method:
import com.mycompany.myproject.MyService
MyService svc = MyService.create
svc.doSomething
Upvotes: 1
Reputation: 5214
I'm not sure if this is exactly what you are looking for, but I'll tell you about a practice that is working for me.
My Java code is plugged together using Google's DI framework called Guice, the API for which I call from within my Scala code. By way of example, here's a module - that's a Guice configuration thing - that binds interfaces to their implementations. The API is a Java API, but I'm interacting with it from Scala code.
class UserSessionModule(storage: ActorRef) extends AbstractModule {
protected def configure: Unit = {
bind(classOf[ActorRef]).
annotatedWith(Names.named("storage")).toInstance(storage)
bind(classOf[UserSession]).toProvider(classOf[UserSessionProvider])
}
}
I've found this to be a very hassle-free approach.
Upvotes: 1
Reputation: 515
I think that the cake pattern is quite good for Scala DI. My favorite article about it is:
Real-World Scala: Dependency Injection (DI) - Jonas Boner
Upvotes: 1