Harry Muscle
Harry Muscle

Reputation: 2387

Grails - Best Way to Access Beans in Normal Groovy Classes

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

Answers (2)

Burt Beckwith
Burt Beckwith

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

micha
micha

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

Related Questions