Reputation: 2387
I'm trying to inject an existing bean into a Groovy class and I know Grails bean injection doesn't work for normal Groovy classes (in src/groovy folder). I can get access to a bean via
Holders.applicationContext.getBean('beanName')
However, I'm wondering if this is the best approach (from a execution speed and memory usage point of view). I will be calling a bean from a method that's called hundreds of times during the normal use of the application and I'm wondering if there might be a better approach. At the very least, should I be storing the bean reference (maybe in the constructor) so that I don't call the above code over and over again? Could I store a static reference to the bean so that each class doesn't have to store its own? Any other suggestions or improvements?
Upvotes: 3
Views: 4827
Reputation: 75671
Your Groovy (or Java) class cannot use dependency injection, but it is very likely called directly or indirectly from a class that can, e.g. a controller or a service. Rather than having this class pull in its dependencies (which runs pretty strongly against the ideas of dependency injection and inversion of control), pass into the class the beans that it needs, or at a minimum the ApplicationContext
if the beans aren't always known up front.
So for example rather than doing this in your service (where Thing
is your src/groovy class):
def someServiceMethod(...) {
def thing = new Thing()
thing.doSomething(42, true)
}
add a dependency injection for the bean it needs in the service and pass it along with the other args, either in the constructor or in individual methods, e.g.
class MyService {
def someBean
def someServiceMethod(...) {
def thing = new Thing(someBean)
thing.doSomething(42, true)
}
}
Upvotes: 2
Reputation: 49582
Groovy classes in src/groovy are not picked up for dependency injection by default. But you can configure them manually by adding a bean definition to conf/spring/resources.groovy
:
import your.class.from.src.groovy.MyBean
beans = {
myBean(MyBean)
}
Using this way you can configure how dependencies should be resolved. You can do this manual, e.g.
myBean(MyBean) {
myService = ref('myService') // assumes you have a MyService bean that can be injected to the `myService` field
}
Or you can use autowiring (what grails does by default for services/controllers):
myBean(MyBean) { bean ->
bean.autowire = 'byName'
}
By adding beans to resources.groovy you can also inject these beans into services and controllers.
For more details see the Spring section in the Grails documentation
Upvotes: 1