AOP – Spring – Intercepting method calls using annotations

Sometimes when using Spring in your app you want to profile your methods to see how long it takes for a method to complete. If you don’t have access to software like JProfiler you can accomplish this quickly with some AOP magic in Spring.
Notice that what’s important about this tutorial is not actually to profile time for methods calls. The real power is to use your custom annotations following the same pattern for this and other purposes such as Security, Cacheing of method return types, Transaction management, you name it…

This tutorial is available for download with svn:

svn checkout http://raulrajatutorials.googlecode.com/svn/trunk/ raulrajatutorials-read-only

Comments in the code itself should be self-explanatory if you already have some java + spring experience

And now to the point.

applicationContext.xml

<?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.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
 
    <!-- A Service that performs some work -->
    <bean id="businessService" class="com.raulraja.service.impl.BusinessServiceImpl"/>
 
    <!-- A service interceptor that intercepts other services with methods annotated with @Profile -->
    <bean id="methodTimeProfiler" class="com.raulraja.util.aop.profile.MethodProfiler"/>
    <aop:config>
        <aop:aspect ref="methodTimeProfiler">
            <aop:pointcut id="profiledMethods" expression="@annotation(com.raulraja.util.aop.profile.Profile)"/>
            <aop:around pointcut-ref="profiledMethods" method="profileMethod"/>
        </aop:aspect>
    </aop:config>
 
    <!--
        This handler is actually not required but used for demonstrating the tutorial by invoking
        http://localhost:port/tutorialName
    -->
    <bean id="serviceInvokerHandler" class="com.raulraja.util.handler.impl.ServiceInvokerHandlerImpl" autowire="autodetect" />
 
</beans>

BusinessServiceImpl.java

package com.raulraja.service.impl;
 
import com.raulraja.service.BusinessService;
import com.raulraja.util.aop.profile.Profile;
import org.apache.log4j.Logger;
 
/**
 * This a very important service impl with methods that is doing something slow and needs to be profiled
 */
public class BusinessServiceImpl implements BusinessService {
 
	private final static Logger logger = Logger.getLogger(BusinessServiceImpl.class);
 
	/**
	 * Do some work , by adding the @Profile annotation the interceptor provides advice
	 */
	@Profile
	public void doSomething() {
		logger.debug("nothing done for simplicity");
	}
}

Profile.java

package com.raulraja.util.aop.profile;
 
/**
 * Marker for methods that will be profiled, By placing this annotation on a method spring will proxy the service and
 * call the interceptor that provides advice to the real method call
 */
public @interface Profile {
}

MethodProfiler.java

package com.raulraja.util.aop.profile;
 
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
 
public class MethodProfiler {
 
	private final static Logger logger = Logger.getLogger(MethodProfiler.class);
 
	/**
	 * Intercepts methods that declare com.company.project.util.aop.profiler.Profile and prints out the time it takes to complete
	 * @param pjp proceeding join point
	 * @return the intercepted method returned object
	 * @throws Throwable in case something goes wrong in the actual method call
	 */
	public Object profileMethod(ProceedingJoinPoint pjp) throws Throwable {
		try {
			final boolean DEBUG = logger.isDebugEnabled();
			long start = System.currentTimeMillis();
			// Parse out the first arg
			String arg1 = "";
			Object[] pjpArgs = pjp.getArgs();
			if ((pjpArgs != null) &amp;&amp; (pjpArgs.length &gt; 0) &amp;&amp; (pjpArgs[0] != null)) {
				arg1 = pjpArgs[0].toString();
			}
			String logPrefix = null;
			if (DEBUG) {
				logPrefix = pjp.getSignature().getDeclaringTypeName() + "." + pjp.getSignature().getName() + " " + arg1;
				logger.debug(logPrefix + " START");
			}
			Object retVal = pjp.proceed();
			long end = System.currentTimeMillis();
			long differenceMs = end - start;
			if (DEBUG) {
				logger.debug(logPrefix + " RETURN in " + differenceMs + " ms");
			}
			return retVal;
		}
		catch (Throwable t) {
			logger.error("Interceptor caught error: " + t, t);
			throw t;
		}
	}
}

And here it is actually running…

picture-8

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • MySpace
  • RSS
  • TwitThis
  • email
  • FriendFeed
  • PDF
  • Slashdot

This post is tagged , , , ,

don't '

3 Responses

  1. Natan Cox says:

    Nice. I’m trying something similar in my production code

    And got
    java.lang.IllegalStateException: Post-processor tried to replace bean instance of type [...] with (proxy) object of type [$Proxy78] – not supported for aspect-configured classes!

    Seems that your solution does not really work to well with code that uses the Spring @Configurable annotation. Any ideas how to get round that?

    @Configurable
    Xyz {
    @Autowired(required = true)
    private OtherService otherService;

    @Timer
    public void timedMethod() {
    }
    }

  2. Raul Raja says:

    Hi Natan,

    I have not looked very deep into this issue but it looks like it might be related to the same problem as described here: http://olafsblog.sysbsb.de/?p=35
    The first response links to the spring docs where it is described how it can be solved using aspectj.

    The docs show how you can create aspectj aspects with spring and use the @Annotation in aspect bean with a @Aspect to intercept methods that contain a given annotation.

    The docs also show how it is compatible with @Configurable.

    http://static.springsource.org/spring/docs/2.5.x/reference/aop.html#aop-using-aspectj

    Let me know if you can’t figure out and I will look further into it as it is interesting to me as well. If you do find it and you feel like sharing feel free to post it as comment.

    Thanks

  3. Natan Cox says:

    Hi Raul,

    That indeed seems to be the problem. I have not looked at it since (too busy) but it is definitely something worth looking at.

    regards, N

Leave a Reply

Comments may be held for moderation, please do not repost. I reserve the right to remove any inappropriate or off-topic comments. If you plan on sharing helpful code, please pass it through Postable first. Want other to know who you are? Register a Gravatar.





Sponsored Links

Categories

Pages

juice141
insurance158
gardens47
jewelers93
bestyoucanfind.info
heart146
james29
lyrics167
industries92
google142
lafayette9
kitchen229
lyrics120
jesus90
italian248
lyrics1
afreeocx.com
guide24
manhattan166
green201
information113
frank168
lyrics160
lyrics190
family142
kofflerboats.com
hitachi214
festival182
forest102
jamaica25
hotel86
executive74
guide23
flavor28
grant172
hockey221
free-microsofts.com
lyrics239
thesagamore.com
failed120
hockey220
healthbenefitsdepot.com
generic67
exchange72
fever194
island235
games21
italy249
manual188
management155
excellpressurewashers.com
library131
gibson97
grill212
marble210
flights35
hotel150
manitoba168
manual186
found137
finance231
house216
install128
institute139
lyric61
garden44
katie169
guitar51
festival181
hotels171
house189
franchise158
columbiatn.com
insurance150
guitar58
illinois22
louisville24
little204
festival189
height163
lyric67
guitar48
lyrics152
lyric48
lacrosse6
hotel154
georgia80
marine233
fitness19
cam.com
hospital62
hunter243
magazine103
floyd73
living210
sex-teen.org
lyrics46
honda22
honey36
mmgins.com
hotel142
ithaca3
lyrics202
lyrics142
management154
lyrics50
hunting247
harold105
creeksidepreserve.com
logic235
forum124
letter111
industrial90
lyrics31
gainesville242
hotel138
island224
heaters152
lyrics171
lyric69
marysvilleohio.org
gauge53
laboratories3
estate2
fields205
infant100
hairstyles77
indian72
james35
ireland214
maine125
houston231
malta148
jones128
fireplace241
honey36
rustyiron.com
finder236
germany90
jessica88
magnum119
fruit195
lyrics235
inurl204
guild36
lyrics37
kennel188
groups248
handbags91
freedom177
jeremy71
lyric81
furnace215
falls129
installing131
manufacturing203
lauderdale58
hotels176
major128
estate25
kenwood198
guitar47
hyderabad7
lyrics129
latex53
fabric103
lonsberry.com
lyrics147
maine123
sunyacc.edu
james27
veostingray.com
landing17
gallery12
lyrics231
madden90
furniture217
lyrics179
fountain146
little197
indian70
lounge27
lyrics121
keygen206
kevin201
import41
foster135
happy95
history199
jones124
kitten231
furniture236
manor170
language22
festival186
flash24
guitar43
lyrics44
homes8
hawaii119
hotel108
madden90
knight236
goneglobal35.com
florist65
myispfinder.org
lyric81
estate12
grand166
estate40
lyrics126
guitars67
fiber195
jumper148
limited160
hamilton85
female171
hospital67
instant132
estate6
glasses123
legal90
level116
pdc.org
estate18
india67
gallery13
kingdom217
florida59
katrina172
lyric76
linux183
football89
ingredients119
gymnastics73
houston229
humidifier241
naral.org
flying75
jewelry102
marine235
internet191
hotel133
hospital54
finder236
katrina172
listing193
lodge228
johnny110
mygibline.com
lyrics231
exhaust83
india54
little196
fuelmaker.com
lyrics163
harrison108
europe51
leather84
luggage33
gallery1
london242
lyrics67
magnum119
italy249
gallery3
lyrics9
london246
24fusion.info
hawaii118
lyric69
great186
thunderwear.com
market243
lyrics200
guide23
james27
linux179
houston222
example60
louisiana21
living211
maison127
californiaduihelp.com
fisher8
lyrics42
horses52
horse46
genesis68
indianapolis82
headphones123
lyrics201
forum123
local219
jelly60
malaysia144
fender177
lyric65
factory116
nomino.ca
greensboro206
express93
humidifier241
lights156
exercise76
girls104
jewish103
honda17
pulaskicountyassessor.net
lyric78
lyric75
harley103
group234
houses217
hockey219
lynch39
machine76
honda31
island229
gymnastics73
harvard114
katie168
infant100
lyrics207
language33
financialhack.com
login238
garcia35
manufacturer202
banana1015.com