Aspect Oriented Programming

As defined on many areas of the Internet, aspect oriented programming (AOP) helps internal_dividersmodularize functionality across multiple areas of your implementation.  Generally, that means you can define functionality in one location, and use it in multiple areas of your solution; without explicitly having to implement/use it where you need it.

In this post, I will define how we can use AOP to insert functionality across our entire implementation; namely, defining default logging across your solution, without needing to implement boilerplate code with every method. 

The Spring Framework is all about AOP implementations.  The Spring Framework is able to implement boilerplate code via annotations that a developer configures on their various classes.  In this post, I will show how we use AOP in a typical Spring-annotated class to insert boilerplate functionality in our application, without having to do that manually.  For the purposes of this post, we will assume our application is a Web application’s backend solution.  But you can apply this simple implementation with any Spring solution.

AspectsstackedPebbles

Aspects, in AOP, can be defined as common features, scattered across methods, classes and class hierarchies. If a class is a key unit of modularity in object oriented programming (OOP), then an aspect is the unit of modularity in AOP.

An aspect is not represented or defined in every class.  It’s implementation is orthogonal to the various class implementations in your solution. Its modular implementation is inserted into your classes, as defined in the aspect.  Let’s look at an example.

Logging

Many times, we may want to look at logging information when trying to resolve a problem or debug an issue. Namely, we may create “Entering method” and “Exiting method” log entries when entering and exiting a Java method, respectively.  We might also want to capture parameter values while logging, to give more meaningful log entries.  Rather than implementing that logging in every method, we can create an aspect, defined in one class, propagated to every method called in a respective session.

See the code below. It outlines the implementation for inserting logging aspects into every method.

@Aspect
@Component
public class ModelsLogger {

   /** Handle to the log file */
    private final Log log = LogFactory.getLog(getClass());

    /** Executed at the beginning of every method call, for the given package **/
    @Before("execution(* com.ricardorodriguezfl..*.*(..))")
    public void logMethodAccessBefore(JoinPoint joinPoint) {
        log.info("***** Starting " + joinPoint.getSignature().getDeclaringType().getSimpleName().toUpperCase() + ": " + joinPoint.getSignature().getName() + " *****");
    }

    /** Executed at the end of every method call, for the given package **/
    @AfterReturning("execution(* com.ricardorodriguezfl..*.*(..))")
    public void logMethodAccessAfter(JoinPoint joinPoint) {
        log.info("***** Completed " + joinPoint.getSignature().getDeclaringType().getSimpleName().toUpperCase() + ": " + joinPoint.getSignature().getName() + " *****");
    }
}

The @Aspect annotation tells the Spring framework that this class represents an aspect. Its implementation will therefore be inspected for insertion into every Java object in a package or series of packages it defines.

The @Component annotation describes this class as one that should be auto-configured bycoding the Spring Framework, so that a ModelsLogger bean is made available in the application context; so that it implements the aspect.  You can read more about Spring Boot and the various auto configuration annotations here. Read more about my personal views on Spring Boot and its benefits, contrasted with another framework, here.

Note the @Before and @AfterReturning annotations.  These help define the methods in the aspect that will be executed before and after a method returns. Each annotation needs a definition of the packages to look at, when inserting the respective functionality.  In my example above, every class that is under the com.ricardorodriguezfl package will be inspected, and this aspect’s before and after functionality will be added to every one of the class’ methods.

Note the JoinPoint method parameters.  In Spring AOP, a JoinPoint always represents a method execution.  You can use the JoinPoint object to get various method information, like a method name and its parameters.  You can read more about Spring AOP here.

So with one class and two methods, we have implemented logging across multiple, if not tens or hundreds of Java classes. That is powerful. Although a simple example, you can imagine inserting functionality for any number of business needs.

Spring AOP Examples

A great example of a cross-cutting concerns in the Spring Framework is their transaction Spring-AOPmanagement library.

The Spring Framework transaction management is implemented through aspects or cross-cutting concerns.  For instance, with the Spring Framework transaction management library, simply adding @Transaction on a method will give you boilerplate “roll-back” functionality on runtime exceptions, without needing to do any additional configuration.  The annotation functionality is defined in its own aspect.  You can read more about the Spring Framework transaction library here.

As a side note, if there’s only one reason to use the Spring Framework in your Web projects, it’s for its transaction management library.

Conclusion

With one class, you are able to insert a host of functionality across your entire program. This makes for a powerful tool when managing and maintaining various business requirements in one location.  If you have any comments or questions, please don’t hesitate to add them in the comments section below.

Aggregation of interesting links in this post

About Rick

I am a father, husband and software engineer, trying to stay active, both in my personal and professional communities. I enjoy programming and building Web applications.
This entry was posted in AOP, java, REST, Spring, Web. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s