Inject Grails Service class into generic Spring Bean

Having gained some measure of working experience with, and become an advocate of, the Grails framework of late, I thought I’d post some occasional tips that may help others along the way.

To help maintain a clean separation of concerns within your Grails application, you might find it desirable to maintain complex business logic outside of the context of Grails service and controller objects. Grails service objects can support transactions at a per-instance level and are maintained by the Grails application context in a way that make them great for a DAO-style pattern implementation. In fact, I prefer to keep all of my GORM-related interactions isolated to service objects rather than sprinkling them between controllers and services. Still, I believe you should avoid weighting service objects down with with complex business logic and calculations. Instead, traditional Spring Beans can be leveraged to aid comprehension and maintenance.

As within traditional Spring application, Spring Beans in Grails start life as simple POJOs or POGOs. They are added to the $app/src/groovy and $app/src/java folders.


public MyPlainSpringBean {
def doComplexLogic() {
}
}

Making a POJO or a POGO a Spring Bean is just a matter of initializing the class instances within the underlying Spring Application context. Do this by editing the beans closure in the $app/conf/spring/resources.groovy file.

beans = {
myPlainSpringBean(MyPlainSpringBean) {}
}

Now you can use dependency injection to get a handle to the Spring Bean with your complex logic. Usually, I add these dependencies to service classes but you can also add them to controllers.


class MyController {
MyPlainSPringBean myPlainSpringBean
def index() {
myPlainSpringBean.doComplexLogic
}
}

Great so far. But say you’d also like your Spring Bean to access the persistence layer to say, store the results of a calculation? In this case, it may make sense to leverage your Grails service object(s). Grails service objects are essentially just Spring Beans themselves with some additional management performed on behalf of the Grails application container. As we saw, traditional Spring Beans are instantiated in a Grails application by referencing their declarations within the conf/spring/resources.groovy class within the beans block. Now add a reference to the service object.

class MyPlainSpringBean {
MyGrailsService myGrailsService
def doComplexLogic() {
}
}

Then tell Grails to inject an instance of the service object into your Spring Bean during initialization using the ref keyword. This works because the Grails container initializes the Grails services before instantiating your Spring Beans.

beans = {
myPlainSpringBean(MyPlainSpringBean) {
myGrailsService = ref('myGrailsService')
}
}

You can now access your persistence layer while still maintaining all of your GORM interaction within the service object tier.


public MyPlainSpringBean {
MyGrailsService myGrailsService
def doComplexLogic() {
def calculationResults = 1000.00f
myGrailsService.storeCalculations(results)
}
}

2 thoughts on “Inject Grails Service class into generic Spring Bean

Leave a Reply

Your email address will not be published. Required fields are marked *