Is there a way to call a method in a Grails service, from a Scala class that is running on the same JVM? I have see开发者_如何学JAVAn something similar done from Groovy/Griffon but cannot figure out how to accomplish that in Grails. (http://www.jroller.com/aalmiray/entry/griffon_groovy_scala_working_together)
Basically, one of my Grails controllers calls some Scala code, which should return some values asynchronously. So, I guess, the only way to return those values is by calling back a method in a Grails service.
I found a way of doing it, inspired by the link in the question above, and one of the FAQs in the Grails website.
On the Scala side: Declare an object similar to the following:
package scalaCallback
object ScalaCallback{
var cback: {def callback(example: String)} = null
def setCallback(cb: {def callback(example: String)}){
cback = cb
}
def invokeCallback(example: String){
if(callback != null) cback.callback(example)
}
}
On the Grails side:
Create a class in src/groovy similar to the following:
package groovyCallback
import org.codehaus.groovy.grails.commons.ApplicationHolder
class GroovyCallback{
private GroovyCallback() {}
private static final INSTANCE = new GroovyCallback()
static getInstance(){ return INSTANCE }
void callback(String example){
ApplicationHolder.application.mainContext.yourService.yourMethod(example)
}
}
In your BootStrap.groovy init add the following:
scalaCallback.cback = groovyCallback.GroovyCallback.getInstance()
When you call invokeCallback("example") in Scala, it will call yourService.yourMethod("example")
Note: the jar file with your Scala class should be in the lib folder of you Grails application
Your Grails service is a Spring bean. @Autowire the service into your Scala class (it will need to be a bean/@Component) and call the method.
EDIT - added example:
For example (using Java, not Scala but the approach is exactly the same):
Java code calling service:
package grailstest;
@Component
public class ServiceInjectionTester {
@Autowired TestService testService;
public String testTheService() {
return testService.serviceMethod();
}
}
Service:
class TestService {
String serviceMethod() {
return "success"
}
}
In Config.groovy:
grails.spring.bean.packages = [ "grailstest" ]
You can also wire your Java/Scala bean into your Grails classes:
class TestController {
@Autowired
ServiceInjectionTester serviceInjectionTester
def index = {
render(text: serviceInjectionTester.testTheService())
}
}
References:
Grails Reference 8.4 - Using Services from Java
Spring: The Foundation for Grails
精彩评论