Monday, April 11, 2011

Grails: Accessing spring beans in the destory closure of Bootstrap code?

Hello,

I'm looking to access a bean in my destroy closure in the Bootstrap.groovy of my grails project. Any ideas on how to achieve this?

I seem to have no access to servletContext...?

From stackoverflow
  • Hmm, I can't find any examples of anyone even using the destroy block closure in Bootstrap. From the docs:

        It is not guaranteed that {{destroy}} will be called unless the 
    application exits gracefully (for example by using the application 
    server's shutdown command) so don't rely on it too much 
    

    As a guess, I'd have to say that the servletContext has already been destroyed before the {{destroy}} closure of Bootstrap is executed, so that bean you're trying to access is gone already. Can anyone confirm?

  • Hey Willi ;)

    You can obtain a a reference to the applicationContext from everywhere (including the destroy closure of BootStrap) using that chunk of code:

    def ctx = org.codehaus.groovy.grails.web.context.ServletContextHolder.servletContext.getAttribute(org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes.APPLICATION_CONTEXT);
    

    or

    def ctx = org.codehaus.groovy.grails.commons.ApplicationHolder.application.parentContext
    

    Getting a reference to a bean is as easy as ctx.beanName.

    Here is a small util class (written in Java) that can simplify this task:

    import org.springframework.context.ApplicationContext;
    import org.codehaus.groovy.grails.web.context.ServletContextHolder;
    import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes;
    
    public class SpringUtil {
    
        public static ApplicationContext getCtx() {
            return getApplicationContext();
        }
    
        public static ApplicationContext getApplicationContext() {
            return (ApplicationContext) ServletContextHolder.getServletContext().getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT);
        }
    
        @SuppressWarnings("unchecked")
        public static <T> T getBean(String beanName) {
            return (T) getApplicationContext().getBean(beanName);
        }
    
    }
    

    and an example:

    def bean = SpringUtil.getBean("beanName")
    

    Cheers, Sigi

  • I know I'm all late here and all but since I found this via Google...

    Your BootStrap class gets injected with Spring beans by name, just like all the services and controllers and stuff. If you want a bean, just def it by name and it'll show up. Otherwise, just def grailsApplication and go to grailsApplication.mainContext.getBean etc.

0 comments:

Post a Comment