Aspect Oriented Programming with Spring AOP

Aspect Oriented Programming (AOP) refers to the programming paradigm which isolates secondary or supporting functions from the main program’s business logic. AOP is a promising technology for separating crosscutting concerns, something usually hard to do in object-oriented programming. The application’s modularity is increased in that way and its maintenance becomes significantly easier.

The most prominent example of a crosscutting concern is logging. Logging is used mainly for debugging and troubleshooting issues mainly by tracing method calls and overall execution flow. It qualifies as a crosscutting concern because a logging strategy necessarily affects every logged part of the system. Logging thereby crosscuts all logged classes and methods.

Note that AOP and OOP are not exclusive. In contrary, they complement each other and their combined use can help us produce robust and maintainable software. With AOP, we start by implementing our project using our OO language and then we deal separately with crosscutting concerns in our code by implementing aspects.

(NOTE: The original post has been slightly edited to improve readability)

While developing software applications for a business we receive the project’s requirements either from the requirements gathering team or from our business analysts. In general, those requirements are functional requirements which represent the activities that the business is doing. However, when developing software applications, apart from the functional requirements, we should also consider some other points like performance, transaction management, security, logging etc. These are called non-functional requirements.

Let us consider a BookStore application which provides web access to a book store. A user can browse the various categories of books, add some books to a cart and finally checkout, do payment and get the books. For this app we might receive the requirements from a business analyst as follows:

A login/registration screen to enter into BookStore.

Users should be able to browse through various categories of books

Users should be able to search books by name, author name, publisher

Users should be able to add/remove the books to/from their cart

Users should be able to see what items currently exist in their cart

Users should be able to checkout and pay the corresponding amount through some payment gateway

A successful message should be shown to users with all the details of their purchases.

A failure message should be shown to users with the cause of failure.

A BookStore administrator/manager should be granted access to add/remove/update book details.

All the above requirements fall under the “Functional Requirements” category. While implementing the above, we should also take care of the following things even though they are not explicitly mentioned:

Role based access to the UI. Here, only Administrators/Managers should have access to add/remove/update book details. [Role based Authorization]

Atomicity in Purchasing. Suppose a user logged into the BookStore and added 5 books into his cart, checked out and completed his payment. In the back-end implementation we may need to enter this purchase details in 3 tables. If after inserting the data into 2 tables the system crashed, the whole operation should be rolled-back. [Transaction Management].

No one is perfect and no system is flawless. So if something went wrong and the development team has to figure it out what went wrong, logging will be useful. So, logging should be implemented in such a way that developer should be able to figure out where exactly the application failed and fix it. [Logging]

The above implicit requirements are called Non-Functional Requirements. In addition to the above, performance should obviously be a crucial non-functional requirement for all public facing websites.

So, with all the above functional requirements we can build the system by decomposing it into various components band taking care of the non-functional requirements through out the components.

In the code above , the functional requirement implementation and non-functional requirement implementation are mingled in the same place. Logging is placed across the OrderService and OrderDAO classes. At the same time, transaction management is spanned across DAOs.

With this approach we have several issues:

The classes need to be changed either to change functional or non-functional requirements. For example: At some point later in the development if the Team decides to log the Method Entry/Exit information along with TimeStamp, we need to change almost all the classes.

The Transaction Management code setting the auto-commit to false in the beginning, doing the DB operations, committing/rollbacking the operation logic will be duplicated across all the DAOs.

This kind of requirements which span across the modules/components is referred to as Cross Cutting Concerns. To better design the system we should separate these cross cutting concerns from the actual business logic so that it will be easier to change or enhance or maintain the application at a later point.

Aspect Oriented Programming is a methodology which enables the separation of the cross cutting concerns from the actual business logic. So, let us follow the AOP methodology and redesign the above two classes separating the cross cutting concerns.

Now lets create a LoggingInterceptor implementing how logging should be done and create a Proxy for OrderService which takes the call from the caller, logs the entry/exit entries using LoggingInterceptor and finally delegates to the actual OrderService.

By using Dynamic Proxies we can separate out the implementation of the cross cutting concerns (such as logging) from actual business logic as follows:

There are several AOP frameworks which can be used in order to separate the implementation from the cross cutting concerns.

Spring AOP

AspectJ

JBoss AOP

Let’s see how we can separate out logging from the actual business logic using Spring AOP. Before that, first we need to understand the following terms:

JoinPoint: A joinpoint is a point in the execution of the application where an aspect can be plugged in. This point could be a method being called, an exception being thrown, or even a field being modified.

Pointcut: A pointcut definition matches one or more joinpoints at which advice should be woven. Often you specify these pointcuts using explicit class and method names or through regular expressions that define matching class and method name patterns.

Aspect: An aspect is the merger of advice and pointcuts.

Advice: The job of an aspect is called advice. It is the additional code we apply to the existing model.

SpringAOP supports several types of advices, namely:

Before: This advice weaves the aspect before method call.

AfterReturning: This advice weaves the aspect after method call.

AfterThrowing: This advice weaves the aspect when method throws an Exception.

Around: This advice weaves the aspect before and after method call.

Suppose we have the following ArithmeticCalculator interface and implementation classes.

If multiple Advices have to be applied on the same pointcut, we can specify the order using the @Order annotation on which advices will be applied. In the previous example, @Before will be applied first. Then, @Around will be applied when the add() method is called.

That’s it guys. A very straightforward and explanatory tutorial from Siva, one of our JCG partners.

I’m using @ AfterReturning but the method is being executed within the transaction. Is there any way to configure a @ AfterReturning to execute a transaction code after the end of the bean …. I want after the transaction is closed?

Hi Your article is outstanding.One more thing I just want to know that If @order is not defined on any pointcut and multiple advices are applied on that then what would be order of their execution?? Can you please provide a brief description about this

Newsletter

Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

Email address:

Recent Jobs

No job listings found.

Join Us

With 1,240,600 monthly unique visitors and over 500 authors we are placed among the top Java related sites around. Constantly being on the lookout for partners; we encourage you to join us. So If you have a blog with unique and interesting content then you should check out our JCG partners program. You can also be a guest writer for Java Code Geeks and hone your writing skills!

Disclaimer

All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners. Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.