Tuesday, March 16, 2010

Grails: Intercepting Service class methods - part 2

As a continuation from my earlier post about intercepting Grails Service methods - as it turns out that approach will not work when using flex-remoting. If you want to intercept your services that you expose as Flex services you have to use Spring AOP. Because of a bug: http://jira.codehaus.org/browse/GRAILS-5932 you will have to use the XML version of AOP definition.

To do that you have to create a resources.xml file in grails-app/conf/spring directory and it would look like the following:

 <?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!--
we are defining the AOP beans in the xml file because of this bug which will
not be fixed until 1.2.2 and we are using 1.2.1
http://jira.codehaus.org/browse/GRAILS-5932
aspect are called twice because of the above bug. See
http://n4.nabble.com/Advice-called-2-or-more-times-for-aspect-with-execution-pointcut-Bug-td1588831.html
toward the bottom Graeme says that 1.2.2 will have the fixes, and 1.3 M1 already does have the
fix. For now we have to live with the interceptor called twice.
-->
<bean id="myAroundAspect" class="com.redpointtech.aop.MyAroundAspect" />
<aop:config proxy-target-class="true">
<aop:aspect id="theAspect" ref="myAroundAspect">
<aop:around method="invoke" pointcut="target(com.redpointtech.aop.AOPMarkerInterface)" />
</aop:aspect>
</aop:config>
</beans>


This assumes that you want to intercept any class that implements the AOPMarkerInterface.

The Aspect looks like the following:

 class MyAroundAspect {  
public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
Object returnVal = null
println "MyAroundAspect called...."
returnVal = joinPoint.proceed()
return returnVal
}
}


A couple of take aways:
1) do not try to do what I suggested in my previous blog post. That will NOT work for Flex services
2) do not use resources.groovy and the Spring DSL - there is a bug in the 1.2.x version that prevents that from working. This is suppose to be fixed in the 1.2.2 release ( not yet released) and the 1.3 M1 ( available now )
3) do use resources.xml and define your Aspect the old fashion way - the old ways work just great.

I hope this saves you some time.

No comments: