You are on page 1of 6

What It Means To Mock http://www.javaranch.com/journal/2008/04/spring-aop-proxies.

html

Aspect Oriented Programming in Spring 2.5


Part One: Introduction to Spring AOP and proxies
by Christophe Verr

Advices, pointcuts. Obscure words making me wonder what Aspect-Oriented Programming (AOP) is all about. In fact,
behind these words lie very simple principles. Once the AOP vocabulary has been tackled, using AOP is a matter of practice.
Spring offers different techniques to use AOP, but I think that the variety of choice makes AOP even more confusing. Let's
clear this up, and see how AOP can be used in Spring.

Two AOP implementations can be chosen, as well as two coding styles for each. Confusing, isn't it ?

Spring AOP. It is not aimed to provide a full AOP implementation but it will be more than enough in most cases.
using the @AspectJ annotation style
using the XML configuration style
AspectJ. If Spring AOP is not enough, AspectJ, a Java implementation of AOP, can be easily plugged in.
using the AspectJ language syntax
using the @AspectJ annotation style

Annotations can be used with Java5+. I recommend to go through Spring's reference documentation to decide which one to
choose. It will mainly depend on requirements and taste. I think that understanding Spring AOP is a priority before thinking
of using AspectJ. In this tutorial, we will use Spring AOP only, using both the @AspectJ and XML styles.

Part 1: Introduction to Spring AOP and proxies


Part 2: Spring AOP using @AspectJ Annotation
Part 3: Spring AOP using the XML schema
Part 4: Spring AOP and transactions

It is assumed that you are already comfortable with Spring's dependency injection. If not, you can read this tutorial first. Basic
database knowledge will help too.

AOP, what's the big deal ?


AOP is here to help programmers to separate of crosscutting concerns. What's that ? Imagine ordering an item at an online
shop. When the item is ordered, several database tables may be updated. If a problem occurs during the ordering process,
everything sent to the database should be cancelled (rollback). If the ordering process successfully ends, the ordering should
be committed to the databases.

[Before]

public class OrderServiceImpl implements OrderService {


public void orderItem(Item item, int quantity) {
// Insert item into ORDER table
...
// Update ITEM table, decrement the number of remaining items
...
}
...
}

public class OrderItem {


public void orderItem(Item item, int quantity) {
OrderService orderService = ServiceManager.getOrderService();
orderService.orderItem(item, quantity);
}
}

[After]

public class OrderServiceImpl implements OrderService {


public void orderItem(Item item, int quantity) {
// Start transaction

1 de 6 23/06/2014 19:01
What It Means To Mock http://www.javaranch.com/journal/2008/04/spring-aop-proxies.html

...
// Insert item into ORDER table
...
// Update ITEM table, decrement the number of remaining items
...
// Commit changes
...
}
}

public class OrderItem {


public void orderItem(Item item, int quantity) {
try {
OrderService orderService = ServiceManager.getOrderService();
orderService.orderItem(item, quantity);
} catch( DbException e ) {
// log exception
...
// Rollback transaction
...
}
}
}

All this changes to make one transaction ! And that's just the orderItem() method. All methods that need transactions will
look like this. The OrderServiceImpl's primary objective is only to fetch, insert, update or delete users. It doesn't care about
transactions after all. If transactions could magically start when needed, without the OrderServiceImpl knowing it. Wouldn't it
be great if transactions could be implemented without touching the original object ? That is where AOP comes to the rescue.
A transaction is a crosscutting concern. It may be applied anywhere on top of existing code. Spring not only supports AOP,
but also offers a very useful transaction management system. But before diving into AOP, let's first see an important concept
in Spring AOP: proxies.

Proxy
A proxy is a well-used design pattern. To put it simply, a proxy is an object that looks like another object, but adds special
functionality behind the scene. In Spring, any interface can be proxied. Let's see a simple example to illustrate what a proxy
really is. The Saloon interface:

package com.javaranch.journal.spring.aop;

public interface Saloon {

void openSaloon();
}

A simple implementation of the Saloon, the MooseSaloon :

package com.javaranch.journal.spring.aop;

public class MooseSaloon implements Saloon {

/** Welcome message */


private String greeting;

public void setGreeting(String greeting) {


this.greeting = greeting;
}

public void openSaloon() {


System.out.println("Saloon open [" + getClass() + "/" + toString() + "]");
System.out.println(greeting);
}

The MooseSaloon declared as a simple bean, and a proxy to the MooseSaloon:

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

2 de 6 23/06/2014 19:01
What It Means To Mock http://www.javaranch.com/journal/2008/04/spring-aop-proxies.html

<bean id="mooseSaloon" class="com.javaranch.journal.spring.aop.MooseSaloon">


<property name="greeting"><value>Welcome to the Big Moose Saloon !!</value></property>
</bean>

<bean id="proxySaloon"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>com.javaranch.journal.spring.aop.Saloon</value></property>
<property name="target"><ref local="mooseSaloon"/></property>
</bean>
</beans>

The Main class using both the MooseSaloon and its proxy:

package com.javaranch.journal.spring.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

public static void main(String[] args) {

ApplicationContext ctx = new ClassPathXmlApplicationContext("aop.xml");


// The mooseSaloon pojo
Saloon mooseSaloon = (Saloon)ctx.getBean("mooseSaloon");
mooseSaloon.openSaloon();
System.out.println("mooseSaloon [" + mooseSaloon.getClass() + "]");
System.out.println("--------");
// The mooseSaloon proxy
Saloon proxySaloon = (Saloon)ctx.getBean("proxySaloon");
proxySaloon.openSaloon();
System.out.println("proxySaloon [" + proxySaloon.getClass() + "]");
}
}

Running this application will produce something similar to the following output :

Saloon open [class com.javaranch.journal.spring.aop.MooseSaloon/


com.javaranch.journal.spring.aop.MooseSaloon@bfea1d]
Welcome to the Big Moose Saloon !!
mooseSaloon [class com.javaranch.journal.spring.aop.MooseSaloon]
--------
Saloon open [class com.javaranch.journal.spring.aop.MooseSaloon/
com.javaranch.journal.spring.aop.MooseSaloon@bfea1d]
Welcome to the Big Moose Saloon !!
proxySaloon [class $Proxy0]

You can notice that both the MooseSaloon and its proxy do the same thing. However, both mooseSaloon and proxySaloon are
different classes. The proxy holds a reference to the mooseSaloon and implements the same interface, thus it holds the same
methods implemented by MooseSaloon. What you cannot see yet is that the proxy can add some nifty functionality behind
the hood. But before getting deeper into AOP, let's see some important terminology.

AOP jargon
The AOP terminology may be boring to get on with, but it is necessary to understand these words before going further.

Join point : a particular execution point. For example a method execution, or the handling of an exception.
Advice : simply said, it is the code to execute. For example, starting a transaction.
Pointcut : represents which join point an advice should be applied to
Aspect : pointcuts and advices form an aspect
Target object : the object being advised by some aspects
Weaving : "applying an aspect"

When an aspect is applied to an object, a particular advice will be applied to any join point matching a pointcut's expression.
Starting a transaction could be expressed the following way :

Aspect : start a transaction in methods which need to run in a transactional context


Join point : method is called
Pointcut : every method starting with "insert", "delete", "update"
Advice : start a transaction

3 de 6 23/06/2014 19:01
What It Means To Mock http://www.javaranch.com/journal/2008/04/spring-aop-proxies.html

NOTE: In Spring AOP, only the "execute method" join point is supported.

There are different types of advices

Before advice : executes before a join point


After returning advice : executes after a join point completes without throwing exceptions
After throwing advice : executes after a join point has thrown an exception
After (finally) advice : executes after a join point has finished, not matter if it has thrown an exception or not
Around advice : executes before and after a join point is executed

A simple advice
In the MooseSaloon example, let's apply a simple aspect :

Aspect : log every Saloon methods called


Pointcut : every Saloon methods of the MooseSaloon
Advice : log before the method is called

Don't worry about ProxyBeanFactory and MethodBeforeAdvice gorry details. The point here is just to illustrate what a proxy
does behind the scene. Here is the advice we will apply to our saloon.

package com.javaranch.journal.spring.aop;

import java.lang.reflect.Method;
import java.util.Date;

import org.springframework.aop.MethodBeforeAdvice;

public class SaloonWatcher implements MethodBeforeAdvice {

public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("[" + new Date() + "]" + method.getName() + " called on " + target);
}
}

The MethodBeforeAdvice's before() method will be called before a method of a target bean is called.

Let's now modify the proxy to use this advice:

<bean id="proxySaloon"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>com.javaranch.journal.spring.aop.Saloon</value></property>
<property name="target"><ref local="mooseSaloon"/></property>
<property name="interceptorNames">
<list>
<value>saloonWatcher</value>
</list>
</property>
</bean>

That's all. The Main class and the MooseSaloon class do not change. After execution, the printed information will look like
this:

Saloon open [class com.javaranch.journal.spring.aop.MooseSaloon/


com.javaranch.journal.spring.aop.MooseSaloon@bfea1d]
Welcome to the Big Moose Saloon !!
mooseSaloon [class com.javaranch.journal.spring.aop.MooseSaloon]
--------
[Mon Mar 24 15:14:42 JST 2008]openSaloon called on com.javaranch.journal.spring.aop.MooseSaloon@2a4983
Saloon open [class com.javaranch.journal.spring.aop.MooseSaloon/
com.javaranch.journal.spring.aop.MooseSaloon@bfea1d]
Welcome to the Big Moose Saloon !!
proxySaloon [class $Proxy0]

Isn't that magic ? Not really, it's called AOP, using a proxy. Although the MooseSaloon class was not changed, we managed to
report when a Saloon method is called. Can you now imagine how to manage transactions without modifying the existing
code ?

4 de 6 23/06/2014 19:01
What It Means To Mock http://www.javaranch.com/journal/2008/04/spring-aop-proxies.html

A word on proxying beans


In the above example, there is a MooseSaloon and its proxy. In the main method, the proxy is explicitly instanciated via its
name "proxySaloon". Wouldn't it be cool if we could use a proxy without even knowing it ? Actually, Spring uses a powerful
feature called autoproxying, which will proxy selected beans behind the scene. There are different ways to achieve this. Here
is one using the BeanNameAutoProxyCreator, which automatically create proxies depending on bean names. In part two of
this tutorial, we will see how autoproxying is achieved using the @AspectJ annotations. But to illustrate the concept of
autoproxying, let's modify the Main class, the bean definition file, and use a BeanNameAutoProxyCreator. Let's remove the
proxy from the Main class.

package com.javaranch.journal.spring.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

public static void main(String[] args) {

ApplicationContext ctx = new ClassPathXmlApplicationContext("aop.xml");


// The mooseSaloon pojo
Saloon mooseSaloon = (Saloon)ctx.getBean("mooseSaloon");
mooseSaloon.openSaloon();
System.out.println("mooseSaloon [" + mooseSaloon.getClass() + "]");
}
}

And let's remove it from the definition file too. Instead, we will use the BeanNameAutoProxyCreator to create a proxy
automatically on the MooseSaloon.

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="mooseSaloon" class="com.javaranch.journal.spring.aop.MooseSaloon">


<property name="greeting"><value>Welcome to the Big Moose Saloon !!</value></property>
</bean>

<bean id="saloonWatcher" class="com.javaranch.journal.spring.aop.SaloonWatcher" />

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames"><value>*Saloon</value></property>
<property name="interceptorNames">
<list>
<value>saloonWatcher</value>
</list>
</property>
</bean>
</beans>

A proxy will be created for every bean whose name ends in "Saloon", just like our "mooseSaloon". After executing this new
version, something similar to the following should be printed:

[Mon Mar 24 16:00:56 JST 2008]openSaloon called on com.javaranch.journal.spring.aop.MooseSaloon@5a9de6


Saloon open [class com.javaranch.journal.spring.aop.MooseSaloon/
com.javaranch.journal.spring.aop.MooseSaloon@5a9de6]
Welcome to the Big Moose Saloon !!
mooseSaloon [class $Proxy0]

Amazing, isn't it ? Look at the Main class. Although the "mooseSaloon" bean is obtained from the factory, the log information
has been printed out. The class name is not MooseSaloon, but "$Proxy0". This shows that we are working on the proxy, not
the bean itself.

You've made it
Congratulations, you've made it ! Don't think too much about MethodBeforeAdvice, ProxyBeanFactory or

5 de 6 23/06/2014 19:01
What It Means To Mock http://www.javaranch.com/journal/2008/04/spring-aop-proxies.html

BeanNameAutoProxyCreator. These were used in Spring 1.2, but there are now other ways to use proxies and AOP since
Spring 2.0, which will be the subject of this tutorial's next part. If you have understood what a proxy is, and still remember
what the AOP main keywords are, you're fine for now.

6 de 6 23/06/2014 19:01

You might also like