I have several services implementing a common interface and I want to be able to choose one of them to inject into other services when my application starts up.
I have tried referencing the service implementation from resources.groovy as shown below but then Spring makes a new instance of the selected service and doesn't autowire its dependencies.
How can I get this solution to work? Or is there another way?
class MyService {
Repository repository
interface Repository {
void save(...)
}
}
class MySqlRepositoryService implements MyService.Repository { ... }
class FileRepositoryService implements MyService.Repository { ... }
resources.groovy:
beans = {
...
repository(FileRepositoryService) { }
}
Services in Grails are the place to put the majority of the logic in your application, leaving controllers responsible for handling request flow with redirects and so on.
Perhaps most importantly, Grails uses Spring's transaction management. And as I've already alluded to, many plugins make use of the Spring integration provided with Java libraries. So, a Grails application is really a Spring application.
It's of course possible to retrieve the reference to service from hand-built factory, but in my opinion, the approach you've taken is the best one. I use it myself, because it gathers all the information on configuration phase of the application in one place, so it's easier to track down which implementation is used.
The pitfall with autowiring that you've encountered can be explained very easily. All the classes put in grails-app/services
are automatically configured by Grails as Spring singleton beans with autowiring by name. So the bean definition you've placed in grails-app/conf/resources.groovy
creates another bean, but without the defaults imposed by Grails conventions.
The most straightforward solution is to put the implementation in src/groovy
to avoid duplication of beans and use the following syntax to turn on the autowiring:
beans = {
repository(FileRepositoryService) { bean ->
bean.autowire = 'byName'
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With