Grails - MBean export the Groovy way...

MBean export the Groovy way

Here, I will show you how to export Hibernate's StatisticsService MBean by leveraging Spring's JMX support the Groovy way (if you are looking for the traditional XML-based approach, see here). Grails provides a BeanBuilder class that uses dynamic Groovy to construct bean definitions.

In {{grails-app/conf/spring}}, create a {{resources.groovy}} file like the one below.

import org.springframework.jmx.support.MBeanServerFactoryBean
import org.springframework.jmx.export.MBeanExporter
import org.hibernate.jmx.StatisticsService
import grails.util.GrailsUtil

beans = { //first bean definition hibernateStats(StatisticsService) { statisticsEnabled=true sessionFactory=ref("sessionFactory") }

switch(GrailsUtil.environment) { case "development": //dev environment beans here break

case "test": //test environment beans here break

case "production": //second bean definition mbeanServer(MBeanServerFactoryBean) { locateExistingServerIfPossible=true }

//third bean definition exporter(MBeanExporter) { server = mbeanServer beans = ["org.hibernate:name=statistics":hibernateStats] } break } }

To understand what we have done, I will quote Grails documentation, slightly adapting it to our example.

Basically what is happening here is the name of each method call (in this case {{hibernateStats}}, {{mbeanServer}} and {{exporter}}) maps to the name of the bean in Spring. The first argument to the method is the bean's class, whilst the last argument is a closure. Within the body of the closure you can set properties on the bean by using standard Groovy syntax. Bean references are resolved automatically by using the name of the bean. This can be seen in the example above with the way the {{exporter}} bean resolves the {{mbeanServer}} reference and the {{beans}} reference (a {{Map}} with one entry, {{hibernateStats}}).
Also, notice in the {{hibernateStats}} definition how we set the {{sessionFactory}} property, using the special method {{ref}} which refers to Hibernate's {{sessionFactory}} bean already defined for us by Grails.

The main advantage of this approach over the XML one, is that here we can mix logic in within our bean definitions. The result, in our case, is that instead of maintaining three different XML configuration files for three different environments, we're dealing only with one file. A fine example of how Grails helps us not to break the DRY (Dont Repeat Yourself) principle.