13

I'd like to inject my service in Groovy/src class. The normaln dependency injection doesn't work:

...
def myService
...

I'm able to use this (it works):

def appCtx = ApplicationHolder.application.getMainContext()
def myService = appCtx.getBean("myService");

but the ApplicationHolder is deprecated. Is there any better solution?

Thanks for any suggestion

kuceram
  • 3,795
  • 9
  • 34
  • 54
  • How do you use this 'src class'? Where and how you instantiate it? – Igor Artamonov May 17 '12 at 17:45
  • I use it inside of other Groovy classes (it is instantiated there). There is a facade groovy class which is used by a service what triggers all that procedures. I don't want to pass used service as parameters in order not to pass so much parameters... – kuceram May 23 '12 at 08:22

4 Answers4

29

The replacement of ApplicationHolder can be Holders, you can also use it in static scope:

import grails.util.Holders
...

def myService = Holders.grailsApplication.mainContext.getBean 'myService'
Don Branson
  • 13,631
  • 10
  • 59
  • 101
César
  • 1,608
  • 1
  • 18
  • 23
13

Check following Grails FAQ to get access to the application context from sources in src/groovy - http://grails.org/FAQ#Q: How do I get access to the application context from sources in src/groovy?

There is no ApplicationContextHolder class equivalent to ApplicationHolder. To access to a service class called EmailService from a Groovy class in src/groovy, access the Spring bean using:

import org.codehaus.groovy.grails.web.context.ServletContextHolder as SCH
import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes as GA
def ctx = SCH.servletContext.getAttribute(GA.APPLICATION_CONTEXT)
def emailService = ctx.emailService
Ben W
  • 2,469
  • 1
  • 24
  • 24
  • 1
    While this will allow you to access methods in a service, it will break the services transactionallity. Excerpt from [Declarative Transactions](http://grails.org/doc/latest/guide/services.html#declarativeTransactions): ***Warning: dependency injection is the only way that declarative transactions work. You will not get a transactional service if you use the new operator such as new BookService()*** – ubiquibacon Aug 09 '13 at 15:23
  • 3
    @ubiquibacon - yes but "def emailService = ctx.emailService" will be a transactional service.I am sorry but what is the issue with accessing service like this? – Ben W Aug 09 '13 at 18:16
  • I don't think that qualifies as "dependency injection". I'll have to do some testing to verify that though. – ubiquibacon Aug 09 '13 at 18:20
  • @ubiquibacon what is the result of the investigation? – biniam Jul 14 '15 at 08:00
2

You can easily register new (or override existing) beans by configuring them in grails-app/conf/spring/resources.groovy:

// src/groovy/com/example/MyClass.groovy
class MyClass {
    def myService
    ...
}

// resources.groovy
beans = {
    myclass(com.example.MyClass) {
        myService = ref('myService')
    }
}

Also you can check this question about How to access Grails configuration in Grails 2.0?

Community
  • 1
  • 1
Arturo Herrero
  • 12,772
  • 11
  • 42
  • 73
  • Now I see that this doesn't work for me. I cannot bind a service or other properties in resources.groovy like this: ` import com.path.to.ResidentAtPlace beans = { residentAtPlaceBean(ResidentAtPlace) { someProperty = 45 placeService = ref('placeService') grailsApplication = ref('grailsApplication') } } ` Everything is null in my ResidentAtPlace.groovy Do you see any problem? I'm using Grail 2.0.3 – kuceram May 18 '12 at 12:12
  • the same happens to me, any idea why? – mathifonseca Apr 11 '14 at 21:14
2

Yo can do it from the resources.groovy:

// src/groovy/com/example/MyClass.groovy
class MyClass {
    def myService
    ...
}

// resources.groovy
beans = {
    myclass(com.example.MyClass) {
        myService = ref('myService')
    }
}

or just using the autowired anotation:

// src/groovy/com/example/MyClass.groovy

import org.springframework.beans.factory.annotation.Autowired

class MyClass {
    @Autowired 
    def myService
    ...
}

// resources.groovy
beans = {
    myclass(com.example.MyClass) {}
}
David Chavez
  • 617
  • 3
  • 17