Tuesday, December 16, 2008

Using AOP to Make Calls Asynchronous in Java

I am working on a project called ScoreOut that consists of an application that runs on a phone that interacts with a server via a REST API.  The server is written in Java and makes heavy use of the Spring Framework.  I wanted to start tracking some of the actions that a user takes on the phone and recording those actions in our analytics tables.  For example, we want to record when a user logs in or requests a golf course.  However, we do not want to slow down the response to the client since the customer is probably out on a golf course at that time.  Therefore, it seemed to makes sense to perform any auditing asynchronously.

The server is broken up into services and I already had a service that did auditing.  I added two new methods to it recordClientLogin and recordCourseRetrieval.  I wanted these methods to be run asynchronously but I wanted the asychronousness (if this isn't a word it should be) to be reusable and easily enabled or disabled (easier to unit test when disabled).  This immediately let me to use AOP so I wrote an interceptor.


package com.scoreout.service.interceptor;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* Intecepts a call and makes it asynchronous. If there is an error it is
* simply logged.
*/
public class AsynchronizeInterceptor implements MethodInterceptor
{

/**
* Logger
*/
private static final Log LOG = LogFactory.
getLog(AsynchronizeInterceptor.class);

/**
* This method will always return null since the method is
* invoked asynchronously.
*
* @see org.aopalliance.intercept.MethodInterceptor
*          #invoke(org.aopalliance.intercept.MethodInvocation)
*/
public Object invoke(final MethodInvocation invocation) throws Throwable
{
Thread thread = new Thread()
{
public void run()
{
try
{
invocation.proceed();
} catch (Throwable e)
{
LOG.warn("Asynchronous method invocation failed.", e);
}
}
};

thread.start();

return null;
}
}


So this inteceptor will make any method it intercepts asynchronous running the method on a separate thread and returning immediately.  So now I just needed to add the point cut to the spring application context.

<!-- Turns methods calls into asynchronous method calls -->
<bean id="asynchronizeInterceptor"
class="com.scoreout.service.interceptor.AsynchronizeInterceptor">
</bean>

<!-- Intercept caddie event recording method calls -->
<bean id="asynchronizePointCut"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="asynchronizeInterceptor" />
</property>
<property name="patterns">
<list>
<value>com.scoreout.service.Audit.recordCourseRetrieval*</value>
<value>com.scoreout.service.Audit.recordClientLogin*</value>
</list>
</property>
</bean>


Now anytime I call com.scoreout.service.Audit.recordCourseRetrieval or com.scoreout.service.Audit.recordClientLogin the call will return immediately and the method will be run in the background.  For testing I can easily make these methods synchronous by either removing them from the application context or providing a new application context that does not include this pointcut (I generally prefer the latter).

3 comments:

  1. That was inspiring,

    Keep up the good work,

    Thanks for writing, most people don't bother.

    ReplyDelete
    Replies
    1. chuẩn bị, dựa vào những trận pháp này, đủ để vây khốn năm sao Đấu Thánh, thậm chí là sáu sao Đấu Thánh.

      - Nếu ngươi có những lời này ta an tâm, xem ra ngươi đã sớm chuẩn bị.

      Hỏa Lão cười nói.

      Ba ngày sau chính là thời gian Cực Viêm Chi Địa mở ra, ngoài kết giới Thần Hoàng Tộc, gần trăm hơi thở tràn ngập, những hơi thở này đều là cường giả, thực lực yếu nhất Bát Tinh cửu tinh Đấu dongtam
      mu moi ra hom nay
      tim phong tro
      http://nhatroso.com/
      nhac san cuc manh
      tổng đài tư vấn luật
      http://dichvu.tuvanphapluattructuyen.com/
      văn phòng luật hà nội
      tổng đài tư vấn luật
      thành lập công ty trọn gói
      http://we-cooking.com/
      chém gió
      trung tâm ngoại ngữTôn.

      Ở trên bầu trời, một bóng hình xinh đẹp rơi vào bên ngoài kết giới, thân ảnh màu xanh khẽ nhìn kết giới, lẩm bẩm nói:

      - Còn ba ngày sao, chỉ có đợi thêm ba ngày nữa, không biết hắn có ở trong đó hay không.

      Lẩm bẩm xong, màu thân ảnh xanh lắc mình tiến vào bên trong sơn mạch, chung quanh hơn mười đạo hơi thở ở treeng người Thanh y nữ tử quét qua.

      Delete
  2. Cool, I am Java developers & love to increase my knowledge through reading blogs here I found some of great information about Make Calls Asynchronous in Java. I just check out your code,

    Thanks for the post

    software development company

    ReplyDelete