Aspect Oriented Programming with Spring

Several services, such as login, security, and transaction management, are not part of the primary business logic of the application.

These services are essential for a Web application.

Required to be implemented in every module of the application.

Considered cross-cutting concerns as they cut across multiple modules of the application.

Aspect oriented programming

The logging, security, and transaction services are the cross-cutting concerns for the AService, BService, and CService modules

Disadvantage Of Cross Cutting Concerns

  • The code of cross-cutting concerns is duplicated across several modules of the application.
  • If any change is required in these concerns, you need to update each module that implements these concerns.
  • Even if there are separate modules for these cross-cutting concerns, you need to write the code for calling these services into each module.
  • The application modules also contain code that is not related to their core functionality

Aspect-Oriented Programming (AOP) complements Object-Oriented Programming (OOP) by providing another way of thinking about program structure.The key unit of modularity in OOP is the class, whereas in AOP the unit of modularity is the aspect.

AOP solves the problem of cross-cutting concerns by allowing you to express them in stand-alone modules called aspects.

All the secondary concerns of an application are considered as aspects.Aspects isolate the secondary logic from the primary business logic of the application.

Advantage Of using Aspect Oriented Programming

It provides the pluggable way to dynamically add the additional concern before, after or around the actual logic.

There are 4 methods that starts from a, 2 methods that starts from b

Scenario : I have to maintain log and send notification after calling methods that starts from a.

Problem without AOP : We can call methods (that maintains log and sends notification) from the methods starting with a. In such scenario, we need to write the code in all the 4 methods.

class A{  
public void a1()
{
business logic...
callLog();
}  
public void a2()
{
business logic...
callLog();
sendNoitfication();
}  
public void a3()
{
business logic...
callLog();
sendNoitfication();
}  
public void a4()
{
business logic...
callLog();
sendNoitfication();
}  
public void b1(){...}  
public void b2(){...}  
}  

But, if client says in future, I don't have to send notification, you need to change all the methods. It leads to the maintenance problem.

Solution with AOP : We don't have to call methods from the method. Now we can define the additional concern like maintaining log, sending notification etc. in the method of a class. Its entry is given in the xml file.

In future, if client says to remove the notifier functionality, we need to change only in the xml file. So, maintenance is easy in AOP.

AOP concepts

  • Aspect
  • Join point
  • Advice
  • Pointcut
  • Introduction
  • Target Object
  • Interceptor
  • AOP Proxy
  • Weaving

Aspect: In Spring AOP, aspects are implemented using regular classes or regular classes annotated with the @Aspect annotation.

Declaring an aspect

A regular bean definition in the application context, pointing to a bean class that has the @Aspect annotation:


   


package org.xyz;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class NotVeryUsefulAspect {

}

Join point:Join Points defines the various Execution Points where an Aspect can be applied.

Advice: 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.

Pointcut:A Pointcut or a Pointcut Definition will exactly tell on which Join Points the Aspects will be applied.

Declaring an Pointcut
A pointcut declaration has two parts: a signature comprising a name and any parameters, and a pointcut expression that determines exactly which method executions we are interested in.

In the @AspectJ annotation-style of AOP, a pointcut signature is provided by a regular method definition, and the pointcut expression is indicated using the @Pointcut annotation (the method serving as the pointcut signature must have a void return type).

// the pointcut expression
@Pointcut("execution(* transfer(..))")

// the pointcut signature
private void anyOldTransfer() {}

Supported Pointcut Designators

Spring AOP supports the following AspectJ pointcut designators (PCD) for use in pointcut expressions:

execution - for matching method execution join points, this is the primary pointcut designator you will use when working with Spring AOP

within - limits matching to join points within certain types (simply the execution of a method declared within a matching type when using Spring AOP)

this - limits matching to join points (the execution of methods when using Spring AOP) where the bean reference (Spring AOP proxy) is an instance of the given type

target - limits matching to join points (the execution of methods when using Spring AOP) where the target object (application object being proxied) is an instance of the given type

args - limits matching to join points (the execution of methods when using Spring AOP) where the arguments are instances of the given types

@target - limits matching to join points (the execution of methods when using Spring AOP) where the class of the executing object has an annotation of the given type

@args - limits matching to join points where the runtime type of the actual arguments passed have annotations of the given type(s)

@within - limits matching to join points within types that have the given annotation

@annotation - limits matching to join points where the subject of the join point has the given annotation Because Spring AOP limits matching to only method execution join points.

Some examples of common pointcut expressions are given below.

execution(public * *(..)) :the execution of any public method:

execution(* set*(..)) :the execution of any method with a name beginning with "set":

execution(* com.xyz.service. AccountService.*(..)) : the execution of any method defined by the AccountService interface:

execution(* com.xyz.service.*.*(..)) : the execution of any method defined in the service package:

execution(* com.xyz.service..*.*(..)) :the execution of any method defined in the service package or a sub-package:

within(com.xyz.service.*) :any join point within the service package:

within(com.xyz.service..*) :any join point within the service package or a sub-package:

this(com.xyz.service. AccountService) :any join point where the proxy implements the AccountService interface:

target(com.xyz.service. AccountService) :'this' is more commonly used in a binding form :- see the following section on advice for how to make the proxy object available in the advice body. any join point where the target object implements the AccountService interface:

args(java.io.Serializable) : 'target' is more commonly used in a binding form :- see the following section on advice for how to make the target object available in the advice body. any join point which takes a single parameter, and where the argument passed at runtime is Serializable:

Introduction: declaring additional methods or fields on behalf of a type. Spring AOP allows you to introduce new interfaces (and a corresponding implementation) to any advised object. For example, you could use an introduction to make a bean implement an IsModified interface, to simplify caching.

Introductions (known as inter-type declarations in AspectJ) enable an aspect to declare that advised objects implement a given interface, and to provide an implementation of that interface on behalf of those objects. An introduction is made using the @DeclareParents annotation. This annotation is used to declare that matching types have a new parent (hence the name). For example, given an interface UsageTracked, and an implementation of that interface DefaultUsageTracked, the following aspect declares that all implementors of service interfaces also implement the UsageTracked interface.

@Aspect
public class UsageTracking {

  @DeclareParents(value="com.xzy.myapp.service.*+",
             defaultImpl=DefaultUsageTracked.class)
  public static UsageTracked mixin;
  
  @Before("com.xyz.myapp.SystemArchitecture.
businessService() &&" +
          "this(usageTracked)")
 public void recordUsage(UsageTracked usageTracked)
 {
    usageTracked.incrementUseCount();
 }
  
}

Target object: object being advised by one or more aspects. Also referred to as the advised object. Since Spring AOP is implemented using runtime proxies, this object will always be a proxied object.

AOP proxy: an object created by the AOP framework in order to implement the aspect contracts (advise method executions and so on). In the Spring Framework, an AOP proxy will be a JDK dynamic proxy or a CGLIB proxy.

Weaving: linking aspects with other application types or objects to create an advised object. This can be done at compile time (using the AspectJ compiler, for example), load time, or at runtime. Spring AOP, like other pure Java AOP frameworks, performs weaving at runtime.

Types Of Advice

Before advice: Advice that executes before a join point, but which does not have the ability to prevent execution flow proceeding to the join point (unless it throws an exception).

After returning advice: Advice to be executed after a join point completes normally: for example, if a method returns without throwing an exception.

After throwing advice: Advice to be executed if a method exits by throwing an exception.

After (finally) advice: Advice to be executed regardless of the means by which a join point exits (normal or exceptional return).

Around advice: Advice that surrounds a join point such as a method invocation. This is the most powerful kind of advice. Around advice can perform custom behavior before and after the method invocation. It is also responsible for choosing whether to proceed to the join point or to shortcut the advised method execution by returning its own return value or throwing an exception.

Choosing which AOP declaration style to use

1 Spring AOP or full AspectJ? Use the simplest thing that can work. Spring AOP is simpler than using full AspectJ as there is no requirement to introduce the AspectJ compiler / weaver into your development and build processes. If you only need to advise the execution of operations on Spring beans, then Spring AOP is the right choice. If you need to advise objects not managed by the Spring container (such as domain objects typically), then you will need to use AspectJ.

2 @AspectJ or XML for Spring AOP? The XML style has two disadvantages. Firstly it does not fully encapsulate the implementation of the requirement it addresses in a single place