JavaBeat

  • Home
  • Java
    • Java 7
    • Java 8
    • Java EE
    • Servlets
  • Spring Framework
    • Spring Tutorials
    • Spring 4 Tutorials
    • Spring Boot
  • JSF Tutorials
  • Most Popular
    • Binary Search Tree Traversal
    • Spring Batch Tutorial
    • AngularJS + Spring MVC
    • Spring Data JPA Tutorial
    • Packaging and Deploying Node.js
  • About Us
    • Join Us (JBC)
  • Privacy

Aspect Oriented Programming (AOP) in Spring 2.5

February 20, 2009 by Krishna Srinivasan Leave a Comment

This article publishes the book excerpt from the book Spring 2.5 Aspect Oriented Programming by Massimiliano Dessi.The following are the list of chapters in the book and brief description inside each chapters. If you are interested in receiving the future articles on book reviews and latest news on Java, please subscribe here.

Chapter 1 introduces the ideas that led to Aspect-Oriented Programming. An overview of main concepts of AOP is used to describe components and features provided by Spring AOP, while a set of concise yet clear examples lets the reader discover what can actually be done with AOP.

Chapter 2 describes in detail the fundamentals of AOP in Spring, presenting interfaces and classes introduced in early 1.x versions of the framework. This chapter shows how to use AOP programmatically, to let the reader discover the basis of Spring AOP and the components that implement Aspect-Oriented Programming in Spring.

also read:

  • Spring Framework Interview Questions
  • Introduction to Spring Framework
  • Spring and Hibernate Integration
  • Spring Framework Books (recommended)

Chapter 3 explains how the weaving of AOP components is done using the proxy pattern and JDK or CGLIB implementations. It describes the purpose of proxies and how to use them effectively. Some practical examples show how to use the proxies programmatically, with annotations and with XML; they explain the ProxyFactoryBean and how to make the programmer’s work easier with AutoProxy. The chapter describes also some smart techniques on target sources.

Chapter 4 explains how Spring AOP is supported by AspectJ. Configuration activity is made simpler, more flexible and more powerful, thanks to annotations and the syntax of AspectJ on pointcuts (without which those costructs would not be available). All examples show how to use AspectJ with both annotations and XML. The chapter contains practical recipes for specific cases, such as the injection of dependencies on domain objects, the management of aspects’ priority, the use of different life cycles for Aspects and how to use Load Time Weaving. The chapter ends with some strategies on
how to choose different AOP approaches to fulfil specific requirements.

Chapter 5 describes the design alternatives that can be implemented using AOP. These alternatives are solutions for common requirements: concurrency, caching, and security. Using AOP, they can be achieved in a very elegant and easy way, being at the same time totally transparent for the system where they are applied.

spring-2-5-aspect-oriented-programming-275x275-imad9tahmcerhnfg

Chapter 6 introduces Domain-Driven Development as a alternative way to design applications. The prototype example presented in this chapter is a typical Three-Layer application, where DDD is used for design and AOP is used to inject the dependencies on domain objects. iBatis is used for persistence to the database.

Chapter 7 completes the prototype application started in Chapter 6, showing the application layer and the user interface. The latter is implemented with Spring MVC using annotations. Integration and unit tests are used to verify the correctness of the classes; DBUnit is used to test persistence classes, while some Mock classes are used to test the UI. The chapter contains the configurations for the prototype infrastructure, including autentication and authorization with Spring Security and the JUnit 4.5 test suite.

Chapter 8 describes the development tools needed to include Spring AOP and AspectJ in the Eclipse IDE. The reader can find here detailed istructions on how to configure Eclipse with the plug-ins for Spring and for the AspectJ Development Tool, and how to install the PostgreSQL database and the Apache Tomcat servlet engine. All installation procedures are described for the three main operating systems: Ubuntu Linux, Apple Mac OS X, and
Microsoft Windows XP.

Design with AOP in Spring 2.5

In this chapter, we’re going to examine some design decisions that are important for building better applications. In these design decisions, the AOP plays a signifi cant role because it provides smart solutions to common crosscutting problems.

  • Spring Aspect Oriented Programming (AOP) 

We will look at the following AOP design solutions:

  • Concurrency with AOP
  • Transparent caching with AOP
  • Security with AOP

Designing and implementing an enterprise Java application means not only dealing with the application core business and architecture, but also with some typical enterprise requirements.

We have to defi ne how the application manages concurrency so that the application is robust and does not suffer too badly from an increase in the number of requests. We have to defi ne the caching strategies for the application because we don’t want CPU- or data-intensive operations to be executed over and over.

We have to defi ne roles and profi les, applying security policies and restricting access to application parts, because different kinds of users will probably have different rights and permissions. All these issues require writing additional code that clutters our application business code and reduces its modularity and maintainability.

But we have a choice. We can design our enterprise Java application keeping AOP in mind. This will help us to concentrate on our actual business code, taking away all the infrastructure issues that can otherwise be expressed as crosscutting concerns. This chapter will introduce such issues, and will show how to design and implement solutions to them with Spring 2.5 AOP support.

Concurrency with AOP

Concurrency is the system’s ability to act with several requests simultaneously, such a way that threads don’t corrupt the state of objects when they gain access at the same time.

A number of good books have been written on this subject, such as Concurrent Programming in Java and Java Concurrency in Practice. They deserve much attention, since concurrency is an aspect that’s hard to understand, and not immediately visible to developers. Problems in the area of concurrency are hard to reproduce. However, it’s important to keep concurrency in mind to assure that the application is robust regardless of the number of users it will serve.

If we don’t take into account concurrency and document when and how the problems of concurrency are considered, we will build an application taking some risks by supposing that the CPU will never simultaneously schedule processes on parts of our application that are not thread-safe.

To ensure the building of robust and scalable systems, we use proper patterns. There are JDK packages just for concurrency. They are in the java.util.concurrent package, a result of JSR-166.

One of these patterns is the read-write lock pattern, which consists of is the interface java.util.concurrent.locks.ReadWriteLock and some implementations, one of which is ReentrantReadWriteLock.

The goal of ReadWriteLock is to allow the reading of an object from a virtually endless number of threads, while only one thread at a time can modify it. In this way, the state of the object can never be corrupted because threads reading the object’s state will always read up-to-date data, and the thread modifying the state of the object in question will be able to act without the possibility of the object’s state being corrupted. Another necessary feature is that the result of a thread’s action can be visible to the other threads. The behavior is the same as we could have achieved using synchronized, but when using a read-write lock we are explicitly synchronizing the actions, whereas with synchronized synchronization is implicit. Now let’s see an example of ReadWriteLock on the BankAccountThreadSafe object.

Before the read operation that needs to be safe, we set the read lock. After the read operation, we release the read lock.

Before the write operation that needs to be safe, we set the write lock. After a state modifi cation, we release the write lock.

[code lang=”java”]
package org.springAOP.chapter.five.concurrent;
import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public final class BankAccountThreadSafe {
public BankAccountThreadSafe(Integer id) {
this.id = id;
balance = new Float(0);
startDate = new Date();
}
public BankAccountThreadSafe(Integer id, Float balance) {
this.id = id;
this.balance = balance;
startDate = new Date();
}
public BankAccountThreadSafe(Integer id, Float balance, Date start)
{
this.id = id;
this.balance = balance;
this.startDate = start;
}
public boolean debitOperation(Float debit) {
wLock.lock();
try {
float balance = getBalance();
if (balance < debit) {
return false;
} else {
setBalance(balance – debit);
return true;
}
} finally {
wLock.unlock();
}
}
public void creditOperation(Float credit) {
wLock.lock();
try {
setBalance(getBalance() + credit);
} finally {
wLock.unlock();
}
}
private void setBalance(Float balance) {
wLock.lock();
try {
balance = balance;
} finally {
wLock.unlock();
}
}
public Float getBalance() {
rLock.lock();
try {
return balance;
} finally {
rLock.unlock();
}
}
public Integer getId() {
return id;
}
public Date getStartDate() {
return (Date) startDate.clone();
}
…
private Float balance;
private final Integer id;
private final Date startDate;
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock rLock = lock.readLock();
private final Lock wLock = lock.writeLock();
}
[/code]

BankAccountThreadSafe is a class that doesn’t allow a bank account to be overdrawn (that is, have a negative balance), and it’s an example of a thread-safe class. The final fi elds are set in the constructors, hence implicitly thread-safe. The balance fi eld, on the other hand, is managed in a thread-safe way by the setBalance, getBalance, creditOperation, and debitOperation methods.

In other words, this clas s is correctly programmed, concurrency-wise. The problem is that wherever we would like to have those characteristics, we have to write the same code (especially the finally block containing the lock’s release). We can solve that by writing an aspect that carries out that task for us.
A state modification is execution(void com.mycompany.BankAccount.set*(*))
A safe read is execution(* com.mycompany.BankAccount.getBalance())
[code lang=”java”]
package org.springAOP.chapter.five.concurrent;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.AspectJ.lang.annotation.After;
import org.AspectJ.lang.annotation.Aspect;
import org.AspectJ.lang.annotation.Before;
import org.AspectJ.lang.annotation.Pointcut;
@Aspect
public class BankAccountAspect {
/*pointcuts*/
@Pointcut(
"execution(* org.springAOP.chapter.five.concurrent.BankAccount.
getBalance())")
public void safeRead(){}
@Pointcut(
"execution(* org.springAOP.chapter.five.concurrent.BankAccount.
set*(*))")
public void stateModification(){}
@Pointcut(
"execution(* org.springAOP.chapter.five.concurrent.BankAccount.
getId())")
public void getId(){}
@Pointcut("execution(* org.springAOP.chapter.five.concurrent.
BankAccount.getStartDate()))
public void getStartDate(){}
/*advices*/
@Before("safeRead()")
public void beforeSafeRead() {
rLock.lock();
}
@After("safeRead()")
public void afterSafeRead() {
rLock.unlock();
}
@Before("stateModification()")
public void beforeSafeWrite() {
wLock.lock();
}
@After("stateModification()")
public void afterSafeWrite() {
wLock.unlock();
}
private final ReadWriteLock lock = new
ReentrantReadWriteLock();
private final Lock rLock = lock.readLock();
private final Lock wLock = lock.writeLock();
}
[/code]

The BankAccountAspect class applies the crosscutting functionality. In this case, the functionality is calling the lock and unlock methods on the ReadLock and the WriteLock. The before methods apply the locks with the @Before annotation, while the after methods release the locks as if they were in the fi nal block, with the @After annotation that is always executed (an after-fi nally advice). In this way the BankAccount class can become much easier, clearer, and briefer. It doesn’t need any indication that it can be executed in a thread-safe manner.

[code lang=”java”]
package org.springAOP.chapter.five.concurrent;
import java.util.Date;
public class BankAccount {
public BankAccount(Integer id) {
this.id = id;
this.balance = new Float(0);
this.startDate = new Date();
}
public BankAccount(Integer id, Float balance) {
this.id = id;
this.balance = balance;
this.startDate = new Date();
}
public BankAccount(Integer id, Float balance, Date start) {
this.id = id;
this.balance = balance;
this.startDate = start;
}
public boolean debitOperation(Float debit) {
float balance = getBalance();
if (balance < debit) {
return false;
} else {
setBalance(balance – debit);
return true;
}
}
public void creditOperation(Float credit) {
setBalance(getBalance() + credit);
}
private void setBalance(Float balance) {
this.balance = balance;
}
public Float getBalance() {
return balance;
}
public Integer getId() {
return id;
}
public Date getStartDate() {
return (Date) startDate.clone();
}
private Float balance;
private final Integer id;
private final Date startDate;
}
[/code]

Another good design choice, together with the use of ReadWriteLock when necessary, is using objects that once built are immutable, and therefore, not
corruptible and can be easily shared between threads.

Transparent caching with AOP

Often, the objects that compose applications perform the same operations with the same arguments and obtain the same results. Sometimes, these operations are costly in terms of CPU usage, or may be there is a lot of I/O going on while executing those operations.

To get better results in terms of speed and resources used, it’s suggested to use a cache. We can store in it the results corresponding to the methods’ invocations as key-value pairs: method and arguments as key and return object as value.

Once you decide to use a cache you’re just halfway. In fact, you must decide which part of the application is going to use the cache. Let’s think about a web application backed by a database. Such a web application usually involves Data Access Objects (DAOs), which access the relational database. Such objects are usually a bottleneck in the application as there is a lot of I/O going on. In other words, a cache can be used there.

The cache can also be used by the business layer that has already aggregated and elaborated data retrieved from repositories, or it can be used by the presentation layer putting formatted presentation templates in the cache, or even by the authentication system that keeps roles according to an authenticated username.

There are almost no limits as to how you can optimize an application and make it faster. The only price you pay is having RAM to dedicate the objects that are to be kept in memory, besides paying attention to the rules on how to manage the life of the objects in cache.

After these preliminary remarks, using a cache could seem common and obvious. A cache essentially acts as a hash into which key-value pairs are put. The keys are used to retrieve objects from the cache. Caching usually has confi guration parameters that allow you to change its behavior.

Now let’s have a look at an example with ehcache (http://ehcache.sourceforge. net). First of all let’s configure it with the name methodCache so that we have at the most 1000 objects. The objects are inactive for a maximum of fi ve minutes, with a maximum life of 10 minutes. If the objects count is over 1000, ehcache saves them on the filesystem, in java.io.tmpdir.

[code lang=”java”]
<ehcache>
…
<diskStore path="java.io.tmpdir"/>
….
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
/>
…
<cache name="methodCache"
maxElementsInMemory="1000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
/>
</ehcache>
[/code]

Now let’s create a CacheAspect. Let’s defi ne the cacheObject to which the ProceedingJoinPoint is passed. Let’s recover an unambiguous key from the
ProceedingJoinPoint with the method getCacheKey. We will use this key to put the objects into the cache and to recover them.

Once we have obtained the key, we ask to cache the Element with the instruction cache.get(cacheKey). The Element has to be evaluated because it may be null if the cache didn’t fi nd an Element with the passed cacheKey.

If the Element is null, advice invokes the method proceed(), and puts in the cache the Element with the key corresponding to the invocation. Otherwise, if the Element recovered from the cache is not null, the method isn’t invoked on the target class, and the value taken from the cache is returned to the caller.

[code lang=”java”]
package org.springaop.chapter.five.cache;
import it.springaop.utils.Constants;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
public class CacheAspect {
public Object cacheObject(ProceedingJoinPoint pjp) throws Throwable
{
Object result;
String cacheKey = getCacheKey(pjp);
Element element = (Element) cache.get(cacheKey);
logger.info(new StringBuilder("CacheAspect invoke:").append("\n
get:")
.append(cacheKey).append(" value:").append(element).
toString());
if (element == null) {
result = pjp.proceed();
element = new Element(cacheKey, result);
cache.put(element);
logger.info(new StringBuilder("\n put:").append(cacheKey).
append(
" value:").append(result).toString());
}
return element.getValue();
}
public void flush() {
cache.flush();
}
private String getCacheKey(ProceedingJoinPoint pjp) {
String targetName = pjp.getTarget().getClass().getSimpleName();
String methodName = pjp.getSignature().getName();
Object[] arguments = pjp.getArgs();
StringBuilder sb = new StringBuilder();
sb.append(targetName).append(".").append(methodName);
if ((arguments != null) &amp;&amp; (arguments.length != 0)) {
for (int i = 0; i &lt; arguments.length; i++) {
sb.append(".").append(arguments[i]);
}
}
return sb.toString();
}
public void setCache(Cache cache) {
this.cache = cache;
}
private Cache cache;
private Logger logger = Logger.getLogger(Constants.LOG_NAME);
}
Here is applicationContext.xml :
<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-2.5.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-2.5.xsd»> …
<bean id="rockerCacheAspect" >
<property name="cache">
<bean id="bandCache" parent="cache">
<property name="cacheName" value="methodCache" />
</bean>
</property>
</bean>
<!– CACHE config –>
<bean id="cache" abstract="true"
class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager" />
</bean>
<bean id="cacheManager"
class="org.springframework.cache.ehcache.
EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:org/springaop/
chapter/five/cache/ehcache.xml" />
</bean>
…
</beans>
[/code]

The idea about the caching aspect is to avoid repetition in our code base and have a consistent strategy for identifying objects (for example using the hash code of an object) so as to prevent objects from ending up in the cache twice.

Employing an around advice, we can use the cache to make the method invocations return the cached result of a previous invocation of the same method in a totally transparent way. In fact, to the methods of the classes defi ned in the interception rules in pointcuts will be given back the return values drawn from the cache or, if these are not present, they will be invoked and inserted in the cache. In this way, the classes and methods don’t have any knowledge of obtaining values retrieved from the cache. Let’s define the pointcut that intercepts the methods of the class DummyClass.

[code lang=”java”]
<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-2.5.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
…
<aop:config>
<!– Pointcuts –>
<aop:pointcut id="readOperation" expression=
"execution(* org.springaop.chapter.five.cache.DummyClass.get*(..))"
/>
<aop:pointcut id="exitOperation" expression=
"execution(void org.springaop.chapter.five.cache.DummyClass.exit())"
/>
<!– Aspects –>
<aop:aspect id="dummyCacheAspect" ref="rockerCacheAspect">
<aop:around pointcut-ref="readOperation" method="cacheObject" />
<aop:after pointcut-ref="exitOperation" method="flush" />
</aop:aspect>
</aop:config>
…
</beans>
Class DummyClass used to check the cache’s working:
package org.springaop.chapter.five.cache;
public class DummyClass {
public String getFooFighters(){
return "My hero";
}
public String getHives(String year){
if(year.equals("2004")){
return "Walk idiot walk !";}else{
return "Abra Cadaver";
}
}
public String getDandyWarhols(){
return "Ride";
}
public void exit(){
System.out.println("The end.");
}
}
Here is ApplicationContext.xml complete:
<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-2.5.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-2.5.xsd»>

<bean id="dummy"/>
<aop:config>
<!– Pointcuts –>
<aop:pointcut id="readOperation"
expression="execution(* org.springaop.chapter.five.cache.
DummyClass.get*(..))" />
<aop:pointcut id="exitOperation"
expression="execution(void org.springaop.chapter.five.
cache.DummyClass.exit())" />
<!– Aspects –>
<aop:aspect id="dummyCacheAspect" ref="rockerCacheAspect">
<aop:around pointcut-ref="readOperation" method="cacheObject"
/>
<aop:after pointcut-ref="exitOperation" method="flush" />
</aop:aspect>
</aop:config>
<bean id="rockerCacheAspect" >
<property name="cache">
<bean id="bandCache" parent="cache">
<property name="cacheName" value="methodCache" />
</bean>
</property>
</bean>
<!– CACHE config –>
<bean id="cache" abstract="true"
class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager" />
</bean>
<bean id="cacheManager"
class="org.springframework.cache.ehcache.
EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:org/springaop/
chapter/five/cache/ehcache.xml" />
</bean>
</beans>
[/code]

ApplicationContext contains the following beans:

  • The dummy bean, used to test the cache’s working.
  • The readOperation and exitOperation pointcuts.
  • The dummyCacheAspect aspect, with around and after advices.
  • The rockerCacheAspect, which is the implementation of the aspect class that contains the logic of recovery from and insertion into the cache.
  • The cache bean, which is an EhCacheFactoryBean.
  • The cacheManager bean, which is an EhCacheManagerFactoryBean.

Here is the test class:

[code lang=”java”]
package org.springaop.chapter.five.cache;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.
ClassPathXmlApplicationContext;
public class CacheTest {
public static void main(String[] args){
String[] paths = { "org/springaop/chapter/five/cache/
applicationContext.xml" };
ApplicationContext ctx = new ClassPathXmlApplicationContext
(paths);
DummyClass dummy = (DummyClass) ctx.getBean("dummy");
dummy.getFooFighters();
dummy.getHives("2004");
dummy.getDandyWarhols();
dummy.getFooFighters();
dummy.getHives("2004");
dummy.getDandyWarhols();
dummy.exit();
}
}
[/code]

Security with AOP

  • Spring security 3.0 

Security is one of the most important elements of an application. The word “security” covers two concepts:

Authentication is the verifi cation’s process of a principal’s identity; a principal is typically a user. A principal in order to be authenticated
provides a credential that is the password.

Authorization, on the other hand, is the process of granting authorities, which are usually roles, to an authenticated user.

Once a user is authenticated and has roles, he or she can work on the application and perform the actions permitted by an access control list, which according to the user’s roles allows certain operations.

Before Spring Security, the rules of who can do what were usually implemented using custom code and an in-house framework, or using JAAS. Usually, the first type of implementation was a consequence of the second type’s diffi culty.

Unfortunately, though custom-type security fi ts its purposes, it lacks in its main aim. This is because it’s safer to employ a much-used framework that is constantly updated and corrects security problems, rather than having an in-house framework that might be barely tested. Beside these considerations, which should be carefully take into account, defi ning and applying security rules without AOP means causing code tangling and code scattering.

In fact, AOP applied to security solves most of the common practical problems concerning security. In order to solve them we use Spring Security 2.0.x (formerly Acegi Security System for Spring), confi guring it properly to carry out most of the work according to the application’s needs. We will see its confi guration in Chapter 7. Now let’s look just at some parts where AOP intervenes in its confi guration.

For now, we will not deal with the authentications and roles attribution. Instead, we will start from the point at which the decision is taken to authorize a user and to provide him or her with roles to access a certain resource. Taking an actual decision whether or not to allow the user (based on its roles) gain access to the secure resource is the responsibility of the access decision manager.

An access decision manager implements the AccessDecisionManager interface, and in order to carry out his or her job, the manager needs a group of voters which implement the AccessDecisionVoter interface.

The AccessDecisionManagers provided by Spring are:

  • A ffirmativeBased: At least one voter votes to grant access
  • C onsensusBased: A consensus of voters votes to grant access
  • U nanimousBased: All voters vote to abstain or grant access

If none of them is specifi ed, we employ AffirmativeBased with two voters, RoleVoter and AuthenticatedVoter. A voter can vote to grant, deny, or abstain. R oleVoter: This bases its vote on role. If the user has the required role by the required resource, it votes ACCESS_GRANTED. But if the resource doesn’t have a specifi ed role, it votes ACCESS_ABSTAIN. If the resource has a role the user doesn’t have, then it votes ACCESS_DENIED.

AuthenticatedVoter: This votes on the strength of the user’s authentication. A user can be authenticated with:

  • IS_AUTHENTICATED_FULLY
  • IS_AUTHENTICATED_REMEMBERED
  • IS_AUTHENTICATED_ANONYMOUSLY

[code lang=”java”]
AuthenticatedVoter votes ACCESS_GRANTED if the
authentication level is higher than the level requested by the
resource. The highest one is IS_AUTHENTICATED_FULLY.
In the following XML, we see the declaration of the access decision manager:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/security

http://www.springframework.org/schema/security/spring-security-

2.0.4.xsd
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
…
<bean id="accessDecisionManager">
<property name="decisionVoters">
<list>
<bean />
<bean
/>
</list>
</property>
</bean>
</beans>
[/code]

Once we have defi ned the AccessDecisionManager, we can use AOP to decide the roles that are necessary to call the several beans’ methods. We can employ three strategies:

  • Securing methods with security interceptors.
  • Securing methods with pointcuts.
  • Securing methods with annotations.

Securing methods with security interceptors

With security interceptors we can defi ne the roles necessary to execute methods on the bean.

[code lang=”java”]
Let’s have the interface:
public interface FooService {
public Integer getBalance(Integer idAccount);
public void setBalanceAccount(Integer id, Integer balance);
public boolean suspendAccount(Integer id);
}
FooService is implemented by FooServiceImpl, that is confi gured as follows :
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/security

http://www.springframework.org/schema/security/spring-security-

2.0.4.xsd">
…
<bean id="accessDecisionManager">
<property name="decisionVoters">
<list>
<bean
/>
<bean
/>
</list>
</property>
</bean>
…
<bean>
<security:intercept-methods
access-decision-manager-ref="accessDecisionManager">
<security:protect method="org.springaop.chapter.five.
security.FooService.getBalance"
access="ROLE_USER" />
<security:protect
method="org.springaop.chapter.five.security.FooService.
setBalanceAccount"
access="ROLE_ACCOUNTING,ROLE_ADMIN" />
<security:protect method="org.springaop.chapter.five.
security.FooService.suspendAccount"
access="ROLE_ADMIN" />
</security:intercept-methods>
</bean>
…
</beans>
[/code]

We have defined some roles (separated by a comma) that can execute those method we want to be executed by a user that has a particular role. This choice permits us to define roles on methods directly on beans, but makes the confi guration files too long.

Securing methods with pointcuts

With this strategy, it’s possible to defi ne the roles required for the different pointcuts with AspectJ syntax that we defi ne with the tag global-method-security. We use the same rules on the same methods of the interface FooService.

[code lang=”java”]
<global-method-security
access-decision-manager-ref="accessDecisionManager">
<protect-pointcut
expression="execution(* org.springaop.chapter.five.security.
FooService.getBalance(..))"
access="ROLE_USER" />
<protect-pointcut
expression="execution(* org.springaop.chapter.five.security.
FooService.set*(..))"
access="ROLE_ACCOUNTING,ROLE_ADMIN" />
<protect-pointcut
expression="execution(* org.springaop.chapter.five.security.
FooService.suspendAccount(..))"
access="ROLE_ADMIN" />
</global-method-security>
[/code]

When using pointcuts, we don’t have to use interceptors if they can be in confl ict with the execution of methods that we have defi ned in the confi guration. This modality of confi guration is consistent with AspectJ syntax for the definition of pointcuts, making the modality of confi guration of aspects homogeneous. Compared to interceptors, the confi guration is less prolix and dispersive as it concentrates the methods that can be invoked with the different roles at one point.

Securing methods with annotations

We can use annotations to defi ne which roles can be executed by the methods of our classes. We will use the same rules on the same methods of the interface FooService.

[code lang=”java”]
package org.springaop.chapter.five.security;
import org.springframework.security.annotation.Secured;
public class FooServiceImplWithAnnotations implements FooService{
@Secured("ROLE_USER")
public Integer getBalance(Integer idAccount) {
Integer result = 0;
// do something
return result;
}
@Secured( { "ROLE_ACCOUNTING", "ROLE_ADMIN" })
public void setBalanceAccount(Integer id, Integer balance) {
// do something
}
@Secured("ROLE_ADMIN")
public boolean suspendAccount(Integer id) {
boolean result = false;
// do something
return result;
}
}
[/code]

With this strategy, we defi ne the roles within the class, needed for the execution of methods. With this choice we don’t have to confi gure any XML, but we lose the possibility of seeing the roles for the methods present defi ned in a single place.

also read:

  • Spring Framework Interview Questions
  • Introduction to Spring Framework
  • Spring and Hibernate Integration
  • Spring Framework Books (recommended)

Summary

In this chapter we’ve seen how to implement crosscutting functionalities, such as concurrency control, the employment of a cache, and security management. Without AOP those functionalities would be scattered across the application, with the same code duplicated in different modules. With AOP we can have cleaner code, much more concise and easier to maintain and debug. We’ve seen how it is possible to implement these functionalities without having tangled or scattered code, implementing functionalities with aspects and advices.

Other important functionalities are transactions management, application logging, exception management, layout, and others. They will be illustrated in the next twox chapters in a complete and working application.

Filed Under: Spring Framework Tagged With: Book Review, Spring AOP

How to write Throws Advice in Spring AOP?

July 15, 2008 by Krishna Srinivasan Leave a Comment

Throws Advice Example

Throws Advice is used when throwing exception from the business methods. This interceptor will be called when there is any exception, so one can do any logic to candle the exception.

also read:

  • Spring Tutorials
  • Spring 4 Tutorials
  • Spring Interview Questions

For writing the Throws Advice implementation you have to implement ThrowsAdvice interface. This is typed or marker interface. Marker interface doesn’t have any methods. The implementation class will have to implement a method names afterThrowing() which normally takes four parameters. But, passing one parameter is enough.

SpringAopMain.java

[code lang=”java”]
package javabeat.net.spring.aop;

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

/**
* source : www.javabeat.net
*/
public class SpringAopMain {
public static void main(String[] args) {
// Read the configuration file
ApplicationContext ctx = new FileSystemXmlApplicationContext(
"spring-config.xml");

// Instantiate an object
BusinessInterface businessInterface = (BusinessInterface) ctx.getBean("businesslogicbean");

// Execute the public method of the bean
businessInterface.businessLogicMethod();
}
}
[/code]

BusinessInterface.java

[code lang=”java”]
package javabeat.net.spring.aop;

/**
* source : www.javabeat.net
*/
public interface BusinessInterface {
void businessLogicMethod();
}
[/code]

BusinessInterfaceImpl.java

[code lang=”java”]
package javabeat.net.spring.aop;

/**
* source : www.javabeat.net
*/
public class BusinessInterfaceImpl implements BusinessInterface{
public void businessLogicMethod() {
System.out.println("BusinessLogic Method Called");
throw new RuntimeException();
}
}
[/code]

ThrowsAdviceExample.java

[code lang=”java”]
package javabeat.net.spring.aop;

import org.springframework.aop.ThrowsAdvice;

/**
* source : www.javabeat.net
*/
public class ThrowsAdviceExample implements ThrowsAdvice{
public void afterThrowing(RuntimeException runtimeException){
System.out.println("Inside After Throwing");
}
}
[/code]

also read:

  • Spring Books
  • Introduction to Spring Framework
  • Introduction to Spring MVC Framework

spring-config.xml

[code lang=”xml”]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC
"-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<!– Bean configuration –>
<bean id="businesslogicbean"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>javabeat.net.spring.aop.BusinessInterface</value>
</property>
<property name="target">
<ref local="beanTarget" />
</property>
<property name="interceptorNames">
<list>
<value>theTracingThrowsAdvisor</value>
</list>
</property>
</bean>

<!– Bean Classes –>
<bean id="beanTarget" class="javabeat.net.spring.aop.BusinessInterfaceImpl" />

<!– Advisor pointcut definition for before advice –>
<bean id="theTracingThrowsAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="theTracingThrowsAdvice" />
</property>
<property name="pattern">
<value>.*</value>
</property>
</bean>

<!– Advice classes –>
<bean id="theTracingThrowsAdvice"
class="javabeat.net.spring.aop.ThrowsAdviceExample" />

</beans>
[/code]

Filed Under: Spring Framework Tagged With: Spring AOP

How to write Interception Around Advice in Spring AOP?

July 15, 2008 by Krishna Srinivasan Leave a Comment

Interception Around Advice Example

In this tips we explore how to use the Interception Around Advice in Spring’s Aspect Oriented Programming(AOP). Interception Around Advice is fundamental advice type in the Spring framework. Also this advice type is derived from other frameworks like AspectJ. So it is interoporable with other frameworks, other advices in the Spring AOPs are specific to Spring Framework and cannot be used in the other similar frameworks.

also read:

  • Spring Tutorials
  • Spring 4 Tutorials
  • Spring Interview Questions

Interception Around Advice is called on before method calls and after method calls. So, when you need advice for both entry and exit then only use thie advice, Otherwise use other availble simple advices Before Advice or After Returning Advice.
The below example programs demonstrated how to write one simple Around Advice. To write Around Advice you have to implement MethodInterceptor and override the invoke method which takes MethodInvocation as the parameter. To understand more on how it works, please look into the example programs.

SpringAopMain.java

[code lang=”java”]
package javabeat.net.spring.aop;

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

/**
* source : www.javabeat.net
*/
public class SpringAopMain {
public static void main(String[] args) {
// Read the configuration file
ApplicationContext ctx = new FileSystemXmlApplicationContext(
"spring-config.xml");

// Instantiate an object
BusinessInterface businessInterface = (BusinessInterface) ctx.getBean("businesslogicbean");

// Execute the public method of the bean
System.out.println(businessInterface.businessLogicMethod());
}
}
[/code]

BusinessInterface.java

[code lang=”java”]
package javabeat.net.spring.aop;

/**
* source : www.javabeat.net
*/
public interface BusinessInterface {
String businessLogicMethod();
}
[/code]

BusinessInterfaceImpl.java

[code lang=”java”]
package javabeat.net.spring.aop;

/**
* source : www.javabeat.net
*/
public class BusinessInterfaceImpl implements BusinessInterface{
public String businessLogicMethod() {
System.out.println("BusinessLogic Method Called");
return "returnVal";
}
}
[/code]

AroundAdviceExample.java

[code lang=”java”]
package javabeat.net.spring.aop;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
* source : www.javabeat.net
*/
public class AroundAdviceExample implements MethodInterceptor{
public Object invoke(MethodInvocation method) throws Throwable {
System.out.println("Before Invoking Method");
Object val = method.proceed();
System.out.println("After Invoking Method");
return val + "updated value";
}

}
[/code]

also read:

  • Spring Books
  • Introduction to Spring Framework
  • Introduction to Spring MVC Framework

spring-config.xml

[code lang=”xml”]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC
"-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<!– Bean configuration –>
<bean id="businesslogicbean"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>javabeat.net.spring.aop.BusinessInterface</value>
</property>
<property name="target">
<ref local="beanTarget" />
</property>
<property name="interceptorNames">
<list>
<value>theTracingAroundAdvisor</value>
</list>
</property>
</bean>

<!– Bean Classes –>
<bean id="beanTarget" class="javabeat.net.spring.aop.BusinessInterfaceImpl" />

<!– Advisor pointcut definition for before advice –>
<bean id="theTracingAroundAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="theTracingAroundAdvice" />
</property>
<property name="pattern">
<value>.*</value>
</property>
</bean>

<!– Advice classes –>
<bean id="theTracingAroundAdvice"
class="javabeat.net.spring.aop.AroundAdviceExample" />

</beans>
[/code]

Filed Under: Spring Framework Tagged With: Spring AOP

Spring AOP : Aspect Oriented Programming (AOP) in Spring

July 4, 2007 by Krishna Srinivasan Leave a Comment

One of the major features available in the Spring Distribution is the provision for separating the cross-cutting concerns in an Application through the means of Aspect Oriented Programming. Aspect Oriented Programming is sensibly new and it is not a replacement for Object Oriented Programming. In fact, AOP is another way of organizing your Program Structure. This first section of this article looks into the various terminologies that are commonly used in the AOP Environment. Then it moves into the support that is available in the Spring API for embedding Aspects into an Application . Finally the article concludes by giving a Sample Application.

also read:

  • Spring Tutorials
  • Spring 4 Tutorials
  • Spring Interview Questions

Introduction to AOP

Since AOP is relatively new, this section devotes time in explaining the need for Aspect Oriented Programming and the various terminologies that are used within. Let us look into the traditional model of before explaining the various concepts.
Consider the following sample application,
Account.java

[code lang=”java”]public class Account{

public long deposit(long depositAmount){

newAmount = existingAccount + depositAccount;
currentAmount = newAmount;
return currentAmount;

}

public long withdraw(long withdrawalAmount){

if (withdrawalAmount[/code]

The above code models a simple Account Object that provides services for deposit and withdrawal operation in the form of Account.deposit() and Account.withdraw() methods. Suppose say we want to add some bit of the security to the Account class, telling that only users with BankAdmin privilege is allowed to do the operations. With this new requirement being added, let us see the modified class structure below.
Account.java

[code lang=”java”]public class Account{

public long deposit(long depositAmount){

User user = getContext().getUser();
if (user.getRole().equals("BankAdmin"){
newAmount = existingAccount + depositAccount;
currentAmount = newAmount;
}
return currentAmount;

}

public long withdraw(long withdrawalAmount){

User user = getContext().getUser();
if (user.getRole().equals("BankAdmin"){
if (withdrawalAmount[/code]

Assume that getContext().getUser() someway gives the current User object who is invoking the operation. See the modified code mandates the use of adding additional if condition before performing the requested operation. Assume that another requirement for the above Account class is to provide some kind of Logging and Transaction Management Facility. Now the code expands as follows,
Account.java

[code lang=”java”]public class Account{

public long deposit(long depositAmount){

logger.info("Start of deposit method");
Transaction trasaction = getContext().getTransaction();
transaction.begin();
try{
User user = getContext().getUser();
if (user.getRole().equals("BankAdmin"){
newAmount = existingAccount + depositAccount;
currentAmount = newAmount;
}
transaction.commit();
}catch(Exception exception){
transaction.rollback();
}
logger.info("End of deposit method");
return currentAmount;

}

public long withdraw(long withdrawalAmount){

logger.info("Start of withdraw method");
Transaction trasaction = getContext().getTransaction();
transaction.begin();
try{
User user = getContext().getUser();
if (user.getRole().equals("BankAdmin"){
if (withdrawalAmount[/code]

The above code has so many dis-advantages. The very first thing is that as soon as new requirements are coming it is forcing the methods and the logic to change a lot which is against the Software Design. Remember every piece of newly added code has to undergo the Software Development Lifecycle of Development, Testing, Bug Fixing, Development, Testing, …. This, certainly cannot be encouraged in particularly big projects where a single line of code may have multiple dependencies between other Components or other Modules in the Project.

The Solution through AOP

Let us re-visit the Class Structure and the Implementation to reveal the facts. The Account class provides services for depositing and withdrawing the amount. But when you look into the implementation of these services, you can find that apart from the normal business logic, it is doing so many other stuffs like Logging, User Checking and Transaction Management. See the pseudo-code below that explains this.

[code lang=”java”]public void deposit(){

// Transaction Management
// Logging
// Checking for the Privileged User
// Actual Deposit Logic comes here

}

public void withdraw(){

// Transaction Management
// Logging
// Checking for the Privileged User
// Actual Withdraw Logic comes here

}[/code]

From the above pseudo-code, it is clear that Logging, Transaction Management and User Checking which are never part of the Deposit or the Service functionality are made to embed in the implementation for completeness. Specifically, AOP calls this kind of logic that cross-cuts or overlaps the existing business logic as Concerns or Cross-Cutting Concerns. The main idea of AOP is to isolate the cross-cutting concerns from the application code thereby modularizing them as a different entity. It doesn’t mean that because the cross-cutting code has been externalized from the actual implementation, the implementation now doesn’t get the required add-on functionalities. There are ways to specify some kind of relation between the original business code and the Concerns through some techniques which we will see in the subsequent sections.

AOP Terminologies

It is hard to get used with the AOP terminologies at first but a thorough reading of the following section along with the illustrated samples will make it easy. Let us look into the majorly used AOP jargons.

Aspects

An Aspect is a functionality or a feature that cross-cuts over objects. The addition of the functionality makes the code to Unit Test difficult because of its dependencies and the availability of the various components it is referring. For example, in the below example, Logging and Transaction Management are the aspects.

[code lang=”java”]public void businessOperation(BusinessData data){

// Logging
logger.info("Business Method Called");

// Transaction Management Begin
transaction.begin();

// Do the original business operation here

transaction.end();
}[/code]

JoinPoint

Join Points defines the various Execution Points where an Aspect can be applied. For example, consider the following piece of code,

[code lang=”java”]public void someBusinessOperation(BusinessData data){

//Method Start -&gt; Possible aspect code here like logging.

try{
// Original Business Logic here.
}catch(Exception exception){
// Exception -&gt; Aspect code here when some exception is raised.
}finally{
// Finally -&gt; Even possible to have aspect code at this point too.
}

// Method End -&gt; Aspect code here in the end of a method.
}[/code]

In the above code, we can see that it is possible to determine the various points in the execution of the program like Start of the Method, End of the Method, the Exception Block, the Finally Block where a particular piece of Aspect can be made to execute. Such Possible Execution Points in the Application code for embedding Aspects are called Join Points. It is not necessary that an Aspect should be applied to all the possible Join Points.

Pointcut

As mentioned earlier, Join Points refer to the Logical Points wherein a particular Aspect or a Set of Aspects can be applied. A Pointcut or a Pointcut Definition will exactly tell on which Join Points the Aspects will be applied. To make the understanding of this term clearer, consider the following piece of code,

[code lang=”java”]aspect LoggingAspect {}
aspect TransactionManagementAspect {}[/code]

Assume that the above two declarations declare something of type Aspect. Now consider the following piece of code,

[code lang=”java”]public void someMethod(){

//Method Start

try{
// Some Business Logic Code.
}catch(Exception exception){
// Exception handler Code
}finally{
// Finally Handler Code for cleaning resources.
}

// Method End
}[/code]

In the above sample code, the possible execution points, i.e. Join Points, are the start of the method, end of the method, exception block and the finally block. These are the possible points wherein any of the aspects, Logging Aspect or Transaction Management Aspect can be applied. Now consider the following Point Cut definition,

[code lang=”java”]pointcut method_start_end_pointcut(){

// This point cut applies the aspects, logging and transaction, before the
// beginning and the end of the method.

}

pointcut catch_and_finally_pointcut(){

// This point cut applies the aspects, logging and transaction, in the catch
// block (whenever an exception raises) and the finally block.

}[/code]

As clearly defined, it is possible to define a Point Cut that binds the Aspect to a particular Join Point or some Set of Join Points.

Advice

Now that we are clear with the terms like Aspects, Point Cuts and Join Points, let us look into what actually Advice is. To put simple, Advice is the code that implements the Aspect. In general, an Aspect defines the functionality in a more abstract manner. But, it is this Advice that provides a Concrete code Implementation for the Aspect.
In the subsequent sections, we will cover the necessary API in the form of classes and interfaces for supporting the Aspect Oriented Programming in Spring.

Creating Advices in Spring

As mentioned previously, Advice refers to the actual implementation code for an Aspect. Other Aspect Oriented Programming Languages also provide support for Field Aspect, i.e. intercepting a field before its value gets affected. But Spring provides support only Method Aspect. The following are the different types of aspects available in Spring.

  • Before Advice
  • After Advice
  • Throws Advice
  • Around Advice

Before Advice

Before Advice is used to intercept before the method execution starts. In AOP, Before Advice is represented in the form of org.springframework.aop.BeforeAdvice. For example, a System should make security check on users before allowing them to accessing resources. In such a case, we can have a Before Advice that contains code which implements the User Authentication Logic.
Consider the following piece of Code,
Authentication.java

[code lang=”java”]public class Authentication extends BeforeAdvice{

public void before(Method method, Object[] args, Object target) throws Throwable{

if (args[0] instanceof User){
User user = (User)args[0];
// Authenticate if he/she is the right user.
}

}

}[/code]

The above class extends BeforeAdvice, thereby telling that before() method will be called before the execution of the method call. Note that the java.lang.reflect.Method method object represents target method to be invoked, Object[] args refers to the various arguments that are passed on to the method and target refers to the object which is calling the method.
System.java

[code lang=”java”]public class System{

public void login(){
// Apply Authentication Advice here.
}

public void logout(){
// Apply Authentication Advice here too.
}
}[/code]

Note that, till now we have not seen any code that will bind the Advice implementation to the actual calling method. We will see how to do that in the Samples section.

After Advice

After Advice will be useful if some logic has to be executed before Returning the Control within a method execution. This advice is represented by the interface org.springframework.aop.AfterReturningAdvice. For example, it is common in Application to Delete the Session Data and the various information pertaining to a user, after he has logged out from the Application. These are ideal candidates for After Advice.
CleanUpOperation.java

[code lang=”java”]public class CleanUpOperation implements AfterReturningAdvice {

public void afterReturning(Object returnValue, Method method, Object[] args,
Object target) throws Throwable{
// Clean up session and user information.
}

}[/code]

Note that, afterReturning() will be method that will be called once the method returns normal execution. If some exception happens in the method execution the afterReturning() method will never be called.

Throws Advice

When some kind of exception happens during the execution of a method, then to handle the exception properly, Throws Advice can be used through the means of org.springframework.aop.ThrowsAdvice. Note that this interface is a marker interface meaning that it doesn’t have any method within it. The method signature inside the Throws Advice can take any of the following form,

[code lang=”java”]public void afterThrowing(Exception ex)

public void afterThrowing(Method method, Object[] args, Object target,
Exception exception)[/code]

For example, in a File Copy program, if some kind of exception happens in the mid-way then the newly created target file has to be deleted as the partial content in the file doesn’t carry any sensible meaning. It can be easily achieved through the means of Throws Advice.
DeleteFile.java

[code lang=”java”]public class DeleteFile implements ThrowsAdvice{

public void afterThrowing(Method method, Object[] args, Object target,
IOException exception){

String targetFileName = (String)args[2];
// Code to delete the target file.
}

}[/code]

Note that the above method will be called when an Exception, that too of type IOException is thrown by the File Copy Program.

Around Advice

This Advice is very different from the other types of Advice that we have seen before, because of the fact that, this Advice provides finer control whether the target method has to be called or not. Considering the above advices, the return type of the method signature is always void meaning that, the Advice itself cannot change the return arguments of the method call. But Around Advice can even change the return type, thereby returning a brand new object of other type if needed.
Consider the following code,

[code lang=”java”]pubic void relate(Object o1, Object o2){

o1.establishRelation(o2);

}[/code]

Assume that we have a method that provides an Association link between two objects. But before that, we have to we want to ensure that the type of the Objects being passed must conform to a standard, by implementing some interfaces. We can have this arguments check in the Around Advice rather than having it in the actual method implementation. The Around Advice is represented by org.aopalliance.intercept.MethodInterceptor.
ValidateArguments.java

[code lang=”java”]public class ValidateArguments implements MethodInterceptor {

public Object invoke(MethodInvocation invocation) throws Throwable {

Object arguments [] = invocation.getArguments()
if ((arguments[0] instanceof Parent) &amp;&amp; (arguments[1] instanceof Child) ){
Object returnValue = invocation.proceed();
return returnValue;
}
throw new Exception ("Arguments are of wrong type");

}
}[/code]

In the above code, the validation happens over the arguments to check whether they implement the right interface. It is important to make a call to MethodInvocation.proceed(), if we are happy with the arguments validation, else the target method will never gets invoked.

Creating Point Cuts in Spring

Point Cuts define where exactly the Advices have to be applied in various Join Points. Generally they act as Filters for the application of various Advices into the real implementation. Spring defines two types of Point Cuts namely the Static and the Dynamic Point Cuts. The following section covers only about the Static Point Cuts as Dynamic Point Cuts are rarely used.

The Point Cut Interface

Point Cuts in Spring are represented by org.springframework.aop.Pointcut. Let us look into the various components of this interface. Looking at the interface definition will have something like the following,
Pointcut.java

[code lang=”java”]public interface Pointcut{

ClassFilter getClassFilter()
MethodMatcher getMethodMatcher()

}[/code]

The getClassFilter() method returns a ClassFilter object which determines whether the classObject argument passed to the matches() method should be considered for giving Advices. Following is a typical implementation of the ClassFilter interface.
MyClassFilter.java

[code lang=”java”]public class MyClassFilter implements ClassFilter{

public boolean matches(Class classObject){

String className = classObject.getName();
// Check whether the class objects should be advised based on their name.
if (shouldBeAdviced(className) ){
return true;
}
return false;
}
}[/code]

The next interface in consideration is the MethodMatcher which will filter whether various methods within the class should be given Advices. For example, consider the following code,
MyMethodMatcher.java

[code lang=”java”]class MyMethodMatcher implements MethodMatcher{

public boolean matches(Method m, Class targetClass){

String methodName = m.getName();
if (methodName.startsWith("get")){
return true;
}
return false;
}

public boolean isRuntime(){
return false;
}

public boolean matches(Method m, Class target, Object[] args);

// This method wont be called in our case. So, just return false.
return false;
}
}[/code]

In the above code, we have 3 methods defined inside in MethodMatcher interface. The isRuntime() method should return true when we want to go for Dynamic Point cut Inclusion by depending on the values of the arguments, which usually happens at run-time. In our case, we can return false, which means that matches(Method method, Class target, Object[] args) wont be called. The implementation of the 2 argument matches() method essentially says that we want only the getter methods to be advised.
We have convenient concrete classes’ implementation the Point Cut classes which are used to give advices to methods statically. They are

  • NameMatchMethod Pointcut
  • Regular Expression Pointcut

NameMatchMethod Pointcut

Here the name of the methods that are too be given advices can me directly mentioned in the Configuration File. A '*' represents that all the methods in the class should be given Advice. For example consider the following class,
MyClass.java

[code lang=”java”]public class MyClass{

public void method1(){}

public void method2(){}

public void getMethod1()

public void getMethod2()

}[/code]

Suppose we wish that only the methods getMethod1() and getMethod2() should be given Advice by some aspect. In that case, we can have the following Configuration file that achieves this,

[code lang=”java”]

get*[/code]

The Expression get* tells that all method names starting with the method name get will be given Advices. If we want all the methods in the MyClass to be adviced, then the 'value' tag should be given '*' meaning all the methods in the Class.

Regular Expression Pointcut

This kind is used if you want to match the name of the methods in the Class based on Regular Expression. Spring distribution already comes with two supported flavors of Regular Expression namely Perl Regular Expression (represented by org.springframework.aop.support.Perl5RegexpMethodPointcut) and Jdk Regular Expression (represented by org.springframework.aop.support.JdkRegexpMethodPointcut).
Considering the following class,
MyClass.java

[code lang=”java”]public class MyClass{

public void method1(){}

public void method11(){}

public void method2(){}

public void getMethod1()

public void getMethod11()

public void getMethod2()
}[/code]

The Expression 'm*1' matches method1() and method11(), 'getMethod.' matches only getMethod1() and getMethod2(). The Configuration File should be populated with the following information for gaining this kind of support.

[code lang=”java”]

m*1[/code]

Spring AOP Sample Application

Let is illustrate the various types of Advices (Before Advice, After Advice, Throws Advice and Around Advice) that we saw before in this sample Application. For this sample application let us define Adder Service which provides logic for adding two numbers. The various classes involved in Application along with the Advices in the subsequent sections.

Addder.java

This is the interface definition for the Add Service. The interface name is Adder and it has one single method called add() taking two arguments both of type int.
Adder.java

[code lang=”java”]package net.javabeat.spring.aop.introduction.test;

public interface Adder {

public int add(int a,int b);

}[/code]

AdderImpl.java

The implementation class for the Add Service. The logic is as simple as it returns the summation of the two numbers given as arguments. Note that, in the later section we will see how Advices get bound with this Implementation Class.
AdderImpl.java

[code lang=”java”]package net.javabeat.spring.aop.introduction.test;

public class AdderImpl implements Adder {

public int add(int a, int b){
return a+b;
}

}[/code]

Before Advice Implementation

This is the Before Advice for the Adder Implmentation class. This class implements the before() method in the MethodBeforeAdvice interface by simply outputting a message telling that this advice is called.
LogBeforeCallAdvice.java

[code lang=”java”]package net.javabeat.spring.aop.introduction.test;

import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;

public class LogBeforeCallAdvice implements MethodBeforeAdvice{

public void before(Method method, Object[] args, Object target) {
System.out.println("Before Calling the Method");
}

}[/code]

After Advice Implementation

The After Method Call Advice implements the AfterReturningAdvice interface providing implementation for the afterReturning() method. Like the Before Advice implementation, this Advice also outputs a simple message to the console.
LogAfterReturningAdvice.java

[code lang=”java”]package net.javabeat.spring.aop.introduction.test;

import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;

public class LogAfterReturningAdvice implements AfterReturningAdvice{

public void afterReturning(Object returnValue, Method method, Object[] args,
Object target) throws Throwable {

System.out.println("After Normal Return from Method");
}

}[/code]

Throws Advice Implementation

This Advice will be called when some kind of Exception is caught during the method invocation. We have added a simple logic to simlate the exception when the user inputs are 0 and 0.
LogAfterThrowsAdvice.java

[code lang=”java”]package net.javabeat.spring.aop.introduction.test;

import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;

public class LogAfterThrowsAdvice implements ThrowsAdvice{

public void afterThrowing(Method method, Object[] args, Object target,
Exception exception){

System.out.println("Exception is thrown on method " + method.getName());
}

}[/code]

Around Advice Implementation

This Advice takes the entire control during the Method Execution. It decides whether the add() method should be called or not based on the user inputs. Note that, only if the user inputs are not 0 and 0, then the add() method will be called through MethodInvocation.proceed().
LogAroundAdvice.java

[code lang=”java”]package net.javabeat.spring.aop.introduction.test;

import org.aopalliance.intercept.*;

public class LogAroundAdvice implements MethodInterceptor{

public Object invoke(MethodInvocation methodInvocation) throws Throwable {

Object arguments[] = methodInvocation.getArguments();
int number1 = ((Integer)arguments[0]).intValue();
int number2 = ((Integer)arguments[1]).intValue();

if (number1 == 0 &amp;&amp; number2 == 0){
throw new Exception("Dont know how to add 0 and 0!!!");
}
return methodInvocation.proceed();
}
}[/code]

Configuration File

The Configuration File has 3 sections. One section is the Advice Bean Definition Section which is the definition set for all the 4 advices which we saw before. All the advices are given identifiers like 'beforeCall', 'afterCall', 'throwCall' and 'aroundCall'. Then contains the Bean Definition for the Add implementation class which is giving the identifier 'adderImpl'.
The next interesting section is how to bind these advices to the implementation code. For this, we have to depend on ProxyFactory Bean.

This Bean is used to create Proxy objects for the Add Implementation class along with the Advice implementation. Note that the property 'proxyInterfaces' contains the Interface Name for which the proxy class has to ge generated. In our case, it is going to be the Adder interface. The 'interceptorNames' property takes a list of Advices to be applied to the dynamically generated proxy class. We have given all the 4 advices to this property. Finally the implementation class for the Adder service is given in the 'target' property.
aop-test.xml

[code lang=”xml”]
<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.0.xsd">

<!– Advices –>
<bean id = "beforeCall"
class = "net.javabeat.spring.aop.introduction.test.LogBeforeCallAdvice" />

<bean id = "afterCall"
class = "net.javabeat.spring.aop.introduction.test.LogAfterReturningAdvice" />

<bean id = "throwCall"
class = "net.javabeat.spring.aop.introduction.test.LogAfterThrowsAdvice" />

<bean id = "aroundCall"
class = "net.javabeat.spring.aop.introduction.test.LogAroundAdvice" />

<!– Implementation Class –>
<bean id = "adderImpl"
class = "net.javabeat.spring.aop.introduction.test.AdderImpl" />

<!– Proxy Implementation Class –>
<bean id = "adder"
class = "org.springframework.aop.framework.ProxyFactoryBean">

<property name = "proxyInterfaces">
<value>net.javabeat.spring.aop.introduction.test.Adder</value>
</property>

<property name = "interceptorNames">
<list>
<value>beforeCall</value>
<value>afterCall</value>
<value>throwCall</value>
<value>aroundCall</value>
</list>
</property>

<property name = "target">
<ref bean = "adderImpl"/>
</property>
</bean>

</beans>
[/code]

Test Class

Following is the test class for the Adder Service. The code loads the Bean Definition File by depending on the BeanFactory class. Watch carefully in the output for the various Advices getting called. Also, we have made to activate the Simulated Exception by passing 0 and 0 as arguments to the add() method call thereby making use of the Throws Advice.

AdderTest.java

[code lang=”java”]package net.javabeat.spring.aop.introduction.test;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.*;

public class AdderTest {

public static void main(String args[]){

Resource resource = new FileSystemResource("./src/aop-test.xml");
BeanFactory factory = new XmlBeanFactory(resource);
Adder adder = (Adder)factory.getBean("adder");
int result = adder.add(10,10);
System.out.println("Result = " + result);

result = adder.add(0,0);
System.out.println("Result = " + result);
}
}[/code]

also read:

  • Spring Books
  • Introduction to Spring Framework
  • Introduction to Spring MVC Framework

Conclusion

This article provided information on how to use Spring AOP for programming the Aspects in an Application. It started with defining what Aspects are and what are problems in having the Aspects directly embedded into the Application and how to separate them using AOP. It then looked briefly into the various AOP Terminologies like Advice, Point Cut, Join Points etc.

Then it moved on into the various support for creating Advices using Spring AOP. Also covered in brief are the Static Point Cuts like Name Method Match and Regular Expression Point Cuts. Finally the article concluded with a Sample Application that illustrates the usage of different Advices.

Filed Under: Spring Framework Tagged With: Spring AOP

Follow Us

  • Facebook
  • Pinterest

As a participant in the Amazon Services LLC Associates Program, this site may earn from qualifying purchases. We may also earn commissions on purchases from other retail websites.

JavaBeat

FEATURED TUTORIALS

Answered: Using Java to Convert Int to String

What is new in Java 6.0 Collections API?

The Java 6.0 Compiler API

Copyright © by JavaBeat · All rights reserved