AOP


weave various repeating concepts like logging, security, cache, etc into the code as prologues, epilogues or other joint points

AOP Another Definition

It's one of the leakiest abstractions yet invented by computer science PhDs. The idea is that you can define "aspects" - code snippets, usually in form of function prologue/epilogue - and then can attach them to any function, which then gets that prologue and epilogue. The idea is that it would make things like verification of data and code reuse easier. In reality it only removes the code from where it belongs to remote locations and confuses the programmer with unexpected surprising side effects.


One Example

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/
7. Aspect Oriented Programming with Spring

a conceptually very simple method for transferring an amount from one account to another:

void transfer(Account fromAcc, Account toAcc, int amount) throws Exception {
 
  if (fromAcc.getBalance() < amount) {
    throw new InsufficientFundsException();
  }
 
  fromAcc.withdraw(amount);
  toAcc.deposit(amount);
}



It lacks security checks. A database transaction should encapsulate the operation in order to prevent accidental data loss. For diagnostics, the operation should be logged to the system log, and so on.

void transfer(Account fromAcc, Account toAcc, int amount, User user, Logger logger)
  throws Exception {
  logger.info("transferring money...");
  if (! checkUserPermission(user)){
    logger.info("User has no permission.");
    throw new UnauthorizedUserException();
  }
  if (fromAcc.getBalance() < amount) {
    logger.info("Insufficient Funds, sorry");
    throw new InsufficientFundsException();
  }
 
  fromAcc.withdraw(amount);
  toAcc.deposit(amount);
 
  //get database connection
 
  //save transactions

 
  logger.info("Successful transaction.");
}

In the previous example other interests have become tangled with the basic functionality (sometimes called the business logic concern). Transactions, security, and logging all exemplify cross-cutting concerns.

Security-related operations appear scattered across numerous methods, what happens if we need to change the security considerations? It would require a major effort.

Cross-cutting concerns do not get encapsulated in their own modules. This increases system complexity and makes software evolution considerably more difficult.

Aspects can have:
advice: code joined to specified points in the program. advice, and can run it before, after, and around join points.
inter-type declarations: structural members added to other classes

aspect Logger {
 
        void Bank.transfer(Account fromAcc, Account toAcc, int amount, User user, Logger logger)  {
                logger.info("transferring money...");
        }
 
        void Bank.getMoneyBack(User user, int transactionId, Logger logger)  {
                logger.info("User requested money back");
        }
 
        // other crosscutting code...
}


Join Point:
A point in the control flow of a program. Many AOP implementations support method executions and field references as join points.
Point Cut:
A set of joint points. Whenever the program execution reaches one of the join points described in the pointcut, a piece of code associated with the pointcut (called advice) is executed.
Most useful pointcut languages use a syntax like the base language (for example, AspectJ uses Java signatures) and allow reuse through naming and combination.

The join point is a point of execution in the base code where the advice specified in a corresponding pointcut is applied.



Another Example

public class SomeBusinessClass extends OtherBusinessClass { // Core data members // Other data members: Log stream, data-consistency flag // Override methods in the base class public void performSomeOperation(OperationInformation info) { // Ensure authentication // Ensure info satisfies contracts // Lock the object to ensure data-consistency in case other // threads access it // Ensure the cache is up to date // Log the start of operation // ==== Perform the core operation ==== // Log the completion of operation // Unlock the object } // More operations similar to above public void save(PersitanceStorage ps) { } public void load(PersitanceStorage ps) { } }

Weaving example

The weaver, a processor, assembles an individual concern in a process known as weaving. The weaver, in other words, interlaces different execution-logic fragments according to some criteria supplied to it.

On Log

  1. Log each public operation's beginning
  2. Log each public operation's completion
  3. Log any exception thrown by each public operation
public class CreditCardProcessorWithLogging { Logger _logger; public void debit(CreditCard card, Money amount) throws InvalidCardException, NotEnoughAmountException, CardExpiredException { _logger.log("Starting CreditCardProcessor.credit(CreditCard, Money) " + "Card: " + card + " Amount: " + amount); // Debiting logic _logger.log("Completing CreditCardProcessor.credit(CreditCard, Money) " + "Card: " + card + " Amount: " + amount); } public void credit(CreditCard card, Money amount) throws InvalidCardException { System.out.println("Debiting"); _logger.log("Starting CreditCardProcessor.debit(CreditCard, Money) " + "Card: " + card + " Amount: " + amount); // Crediting logic _logger.log("Completing CreditCardProcessor.credit(CreditCard, Money) " + "Card: " + card + " Amount: " + amount); } }

AOP language compilers perform two logical steps:

  1. Combine the individual concerns
  2. Convert the resulting information into executable code

An AOP implementation can implement the weaver in various ways, including source-to-source translation. Here, you preprocess source code for individual aspects to produce weaved source code. The AOP compiler then feeds this converted code to the base language compiler to produce final executable code. For instance, using this approach, a Java-based AOP implementation would convert individual aspects first into Java source code, then let the Java compiler convert it into byte code. The same approach can perform weaving at the byte code level; after all, byte code is still a kind of source code. Moreover, the underlying execution system -- a VM implementation, say -- could be aspect aware. Using this approach for Java-based AOP implementation, for example, the VM would load weaving rules first, then apply those rules to subsequently loaded classes. In other words, it could perform just-in-time aspect weaving.

AspectJ, a freely available AOP implementation for Java



Comments