Book Image

Mockito for Spring

By : Sujoy Acharya
Book Image

Mockito for Spring

By: Sujoy Acharya

Overview of this book

Table of Contents (12 chapters)
Mockito for Spring
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Working with aspects


AOP is one of the key components of Spring Framework. Object-oriented programming fails to deal with technical and functional cross-cutting concerns, such as generic functionalities that are needed in many places in our application.

The following are a few examples of cross-cutting concerns:

  • Logging and tracing

  • Transaction management

  • Security

  • Caching

  • Error handling

  • Performance monitoring

  • Custom business rules

  • Event handling

In our application, we need logging to debug or troubleshoot, so we put debug messages in every method; this is a cross-cutting concern. Similarly, we secure methods for unauthorized access.

AOP overlays a new layer onto the data-driven composition of OOP. This layer corresponds to the cross-cutting functionalities that are difficult to integrate through the OOP paradigm.

AOP is implemented with AspectJ and Spring AOP:

  • AspectJ: This is the original AOP technology (the first version dates from 1995) that offers a full-blown, aspect-oriented programming language and uses bytecode modification for aspect weaving.

  • Spring AOP: This is a Java-based AOP framework and it uses dynamic proxies for aspect weaving. This focuses on using AOP to solve enterprise problems.

The following example demonstrates a cross-cutting concern:

class Account{
  private double balance;
  public void withdraw(double amount){
    logger.debug("Withdraw –"+amount);
    tx.begin();
      balance = this.balance-amount;
      accountDao.saveBalance(balance);
    tx.commit();
  }
}

The withdraw method logs debug information, begins a transaction, performs a database transaction, and finally commits the transaction. In each method, we will introduce duplicate code for debugging and opening and committing a transaction. These are cross-cutting concerns as the conceptually duplicate code will be scattered to all modules in the application. This is bad in the sense that if we need to change any settings, we have to manually change all methods in all modules, such as instead of logger.debug, and if we need to change the logging to logger.info, we need to modify all methods.

Before we dig deep into AOP, let's get familiar with the terminology:

  • Join point: This is a well-defined point during the execution of your application. You can insert additional logic at join points.

    Examples of join points are as follows:

    • Method invocation

    • Class initialization

    • Object initialization

  • Advice: This is the code that is executed at a specific join point. The three types of advice are as follows:

    • The before advice is executed before a join point.

    • The after advice is executed after a join point.

    • The around advice is executed around a join point. The around advice spans the before and after advice.

  • Pointcut: This is a collection of join points to execute an advice. A join point is a possibility of executing an advice, whereas a pointcut is a set of selected join points where actually the advice is executed.

  • Aspect: This defines the implementation of the cross-cutting concern. An aspect is the combination of advice and pointcuts. An application can have any number of aspects, depending on the requirement.

  • Weaving: This is the process of applying aspects into the code at the appropriate join points. There are three types of weaving:

    • Compile-time weaving

    • Class load-time weaving

    • Runtime weaving

  • Target: This is the object that is advised by one or more aspects.

  • Introduction: This is the process by which you can modify the structure of an object by introducing additional methods or fields to it. You use the introduction to make any object implement a specific interface without needing the object's class to implement that interface explicitly.

There are two types of AOP:

  • Static AOP

    • The weaving process forms another step in the build process for an application

    • For example, in a Java program, you can achieve the weaving process by modifying the actual bytecode of the application by changing and modifying the code as necessary

  • Dynamic AOP

    • The weaving process is performed dynamically at runtime

    • It is easy to change the weaving process without recompilation

Spring AOP is based on proxies. To know more about proxies, read about the proxy pattern or visit http://en.wikipedia.org/wiki/Proxy_pattern.

We'll display Hello World! through AOP. The following are the steps to create the hello world message:

  1. Create an interface called IMessageWriter:

    package com.packt.aop;
    
    public interface IMessageWriter {
      void writeMessage();
    }
  2. Create a class called MessageWriter and implement the IMessageWriter interface:

    package com.packt.aop;
    
    public class MessageWriter implements IMessageWriter {
    
      @Override
      public void writeMessage() {
        System.out.print("World");
      }
    
    }
  3. The join point is the invocation of the writeMessage() method. What we need is an around advice as we'll prepend Hello before World and append the exclamation after World to make it Hello World !. The MethodInterceptor interface is AOP Alliance standard interface for around interface. The MethodInvocation object represents the method invocation that is being advised. We'll create an advice as follows:

    import org.aopalliance.intercept.MethodInterceptor;
    import org.aopalliance.intercept.MethodInvocation;
    public class MessageDecorator implements MethodInterceptor {
      public Object invoke(MethodInvocation invocation) 
        throws Throwable {
        System.out.print("Hello ");
        Object retVal = invocation.proceed();
        System.out.println("!");
        return retVal;
      }
    }
  4. We'll use the ProxyFactory class to create the proxy of the target object:

    import org.springframework.aop.framework.ProxyFactory;
    
    public class AOPTest {
    
      public static void main(String[] args) {
        MessageWriter target = new MessageWriter();
        // create the proxy
        ProxyFactory pf = new ProxyFactory();
        // Add the given AOP Alliance advice to the tail
        // of the advice (interceptor) chain
        pf.addAdvice(new MessageDecorator());
        // Set the given object as target
        pf.setTarget(target);
        // Create a new proxy according to the
        // settings in this factory
        MessageWriter proxy = (MessageWriter) 
            pf.getProxy();
        // write the messages
        target.writeMessage();
        System.out.println("");
        // use the proxy
        proxy.writeMessage();
      }
    }

When we run the program, the MessageDecorator around advice is applied on the proxy object. When proxy.writeMessage is called, the correct output is displayed.