Friday, July 31, 2009

Grails: use a session scoped bean in a singleton bean

In my project, I had to change the scope of two of my services from the default scope (singleton) to as session scope. With grails, this is fairly easy, for a service, you simply have to add the following line in you service class:
static scope = 'session'

Now there's a problem if you use this service in a singleton scoped bean like a filter or a taglib for example. The problem is that spring will try to instantiate the singleton bean on startup, then it will try to create the service to inject it in the singleton, but as this does not occur in a session, spring cannot create the service and fails with a BeanCreationException. Anyway, even if the singleton was created within a session, the same service would be used for all sessions as the singleton wouldn't be re-injected for each session.

Fortunately, spring comes with the handy ScopedProxyFactoryBean. As its name implies, it is a proxy factory bean for scoped object. To use it, you first have to declare the service in grails-app/conf/spring/resources.groovy for an application or in the doWithSpring method of the plugin descriptor for a plugin:
sessionScopedService(SessionScopedService) { bean ->
bean.scope = 'session'
}


At the same place, declare the proxy factory bean:
sessionScopeProxy(org.springframework.aop.scope.ScopedProxyFactoryBean) {
targetBean = 'sessionScopedService'
proxyTargetClass = true
}


You can now use the sessionScopeProxy instead of the sessionScopedService in you singleton bean. It will transparently proxy to a session scoped SessionScopeService bean.

4 comments:

  1. I think there's a typo... shouldn't it say:

    sessionScopedService(SessionScopedService) { bean ->
    bean.scope = 'session'
    }

    ReplyDelete
  2. Sorry me again, am just trying it out right now :)

    I think the ScopedProxyFactoryBean uses property targetBeanName, not targetBean. At least with that it's not complaining for me anymore... testing it in 3, 2, 1 ...

    ReplyDelete
  3. Works like a charm, thanks for the posting, it really saved by project!

    ReplyDelete