DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Coding
  3. Frameworks
  4. AOP made easy with AspectJ and Spring

AOP made easy with AspectJ and Spring

Marco Tedone user avatar by
Marco Tedone
·
May. 17, 11 · Interview
Like (0)
Save
Tweet
Share
22.59K Views

Join the DZone community and get the full member experience.

Join For Free

I recently started looking at Aspect Oriented Programming (AOP) and I'm finding it exciting to say the least. Of course I was acquainted with it, since I saw it used for transaction management within Spring but I have never looked at it in depth. In this article I want to show how quick it is to get up to speed with AOP and Spring thanks to AspectJ. The material in this article is based on the excellent AOP book AspectJ in Action by Ramnivas Laddad. 

AOP is not a language, but rather an approach to software engineering. Like any methodology it has got different implementations and  AspectJ is currently the richest and most complete of all. Since AspectJ and AspectWerkz merged, it is now possible to create aspects using annotations.

The reason developers write code is to provide functionality of some sort. The kind of functioniality is not important for this discussion: some might want to deliver business functionality, others might write code for research purposes, other for sheer fun. The point is that any information system has got a core motive, a key functionality which it wants to deliver. For instance, I recently wrote PODAM, a testing tool which has as its ultimate goal that of automatically fill POJO / JavaBean properties.

Every information system has also got needs for orthogonal services (what AOP calls crosscutting concerns); for instance logging, security, auditing, exception management and so on. While an information system can be divided into discrete pieces of functionality (what AOP defines join points), orthogonal services are required across the board. For instance, if one wanted to log how long the execution of every single public method took, each public method should have something like the following pseudo-code:

public void someBusinessMethod() {

long start = System.currentTimeInMilliseconds();

doTheBusinessFunctionality();

long end = System.currentTimeInMilliseconds();

log.debug("The execution of someBusinessMethod took " + (end - start) + " milliseconds");

}

 

In the above method, the core functionality is identified solely by someBusinessMethod() whereas everything else is just logging activity. It would be nice to have something like :

//Some external magic happens before the invocation of this method to take the start time

public void someBusinessMethod() {

doTheBusinessFunctionality();

}

//Some external magic happens after the invocation of this method to take the end time and logs how long the execution took.

Developers typically want logging, security, etc. throughout their application, not for a single method; AOP allows developers to achieve this goal by defining somewhere externally (called an Aspect) the behaviour to apply to all code matching some pattern (AOP actually allows for a broader set of functionalities, such as the possibility to add interfaces, instance variables, methods, etc to a class just to name one). This empowered behaviour is then somewhat added to the final executing code by what AOP calls a Weaver.

There are various ways that this can be achieved: weaving can happen at the source level, at the binary level and at load time. You could think of the weaver as the linker in C and C++; sources and libraries are linked together to create an executable; the weaver combines together Java code and aspects to create empowered behaviour.

Spring achieves this empowered behaviour by creating an AOP proxy around the code whose behaviour must be enriched. The code that follows shows a very simple example based on AspectJ; the example surrounds the execution of a simple method with some Authentication service.

The Authentication services looks very simple (the point is not how the functionality has been implemented but rather that an authentication service is available) :

/**
*
*/
package uk.co.jemos.aop;

/**
* A simple authenticator service.
*
* @author mtedone
*
*/
public class Authenticator {

public void authenticate() {
System.out.println("Authenticated");
}

}

 

Now let's have a look at the business logic:

/**
*
*/
package uk.co.jemos.aop;

/**
* A simple service which delivers messages
* @author mtedone
*
*/
public class MessageCommunicator {

public void deliver(String message) {
System.out.println(message);
}

public void deliver(String person, String message) {
System.out.println(person + ", " + message);
}

}

 

What we would like is for the Authenticator to be invoked before the invocation of any of the business methods of MessageCommunicator. Using AspectJ annotation syntax, we write in Aspect  in pure Java:

package uk.co.jemos.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class SecurityAspect {

private Authenticator authenticator = new Authenticator();

@Pointcut("execution(* uk.co.jemos.aop.MessageCommunicator.deliver(..))")
public void secureAccess() {
};

@Before("secureAccess()")
public void secure() {

System.out.println("Checking and authenticating user...");
authenticator.authenticate();

}

}

 

The code above is a bit more interesting. An Aspect is marked with the @Aspect annotation. A Pointcut is some point of interest in our code, where we would like our Aspect to kick in. The syntax @Pointcut("execution(* uk.co.jemos.aop.MessageCommunicator.deliver(..))")

public void secureAccess() {
};

 

means: "Define a Pointcut named secureAccess which applies to all deliver methods within the MessageCommunicator class, regardless of the return type of such method".

What follows is called an advice, and it's where AOP empowers the behaviour of our class:

@Before("secureAccess()")
public void secure() {

System.out.println("Checking and authenticating user...");
authenticator.authenticate();

}

 

The code above says: "Before any match of the secureAccess() Pointcut apply the code within the block". All of the above is pure Java, although the annotations belong to the AspectJ runtime.

To use the above aspect with Spring, I defined a Spring context file:

<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

<aop:aspectj-autoproxy />

<bean id="messageCommunicator" />

<bean id="securityAspect" />

</beans>

 

The XML element:  <aop:aspectj-autoproxy /> instructs Spring to create a proxy around every aspect.

Now when I use the MessageCommunicator from a client:

/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"classpath:aop-appContext.xml");

MessageCommunicator communicator = ctx.getBean("messageCommunicator",
MessageCommunicator.class);
communicator.deliver("Hello World");
communicator.deliver("Marco", "Hello World");

}

 

I get the following output:

INFO: Loading XML bean definitions from class path resource [aop-appContext.xml]
15-May-2011 11:51:41 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@21b64e6a: defining beans [org.springframework.aop.config.internalAutoProxyCreator,messageCommunicator,securityAspect]; root of factory hierarchy
Checking and authenticating user...
Authenticated
Hello World
Checking and authenticating user...
Authenticated
Marco, Hello World

 

AOP substantially changes the way we think software engineering, by allowing us to externalise crosscutting concerns in external components which are then weaved into our code when needed.This allows for cleaner and more maintainable code and the implementations are limitless. Additionally, if we are careful in writing our Aspects by making them reusable, we can quickly come up with a library of general-purpose, reusable aspects which add functionality to our code in an injected way.

There are obviously drawbacks in the adoption of AOP, mainly the learning curve which is required by developers to get acquainted with the technology. AspectJ defines its own language and syntax, as the example above demonstrates); the @Before annotation is just one possibility: advices can be applied before, after, around objects; additionally the syntax to define Pointcuts is not Java but rather script-like. AspectJ aspects also have keywords and native objects to capture the context of the join points they advice, and this syntax needs to be learned. However, the potential gains outweight by large the extra effort required in learning this new and exciting technology.

Happy Technology!

 

From http://tedone.typepad.com/blog/2011/05/using-aop-easily-with-aspectj-and-spring.html

AspectJ Spring Framework Aspect (computer programming) Information system

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Introduction to Spring Cloud Kubernetes
  • The Power of Docker Images: A Comprehensive Guide to Building From Scratch
  • Implementing PEG in Java
  • DevOps for Developers: Continuous Integration, GitHub Actions, and Sonar Cloud

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: