Wednesday, April 2, 2008

Introduction to AOP-Main Spring Framework Feature(Good Article,Easy to understand)

Introduction to AOP

2.1) The Real Problem

Since AOP is relatively new, this section devotes time in explaining the need for Aspect Oriented Programming and the various terminologies that are used within. Let us look into the traditional model of before explaining the various concepts.

Consider the following sample application,

Account.java

                               
public class Account{
 
    public long deposit(long depositAmount){  
 
        newAmount = existingAccount + depositAccount;
        currentAmount = newAmount;
        return currentAmount;
 
    }
 
    public long withdraw(long withdrawalAmount){
 
        if (withdrawalAmount <= currentAmount){
            currentAmount = currentAmount – withdrawalAmount;
        }
        return currentAmount;
 
    }   
}
                               

The above code models a simple Account Object that provides services for deposit and withdrawal operation in the form of Account.deposit() and Account.withdraw() methods. Suppose say we want to add some bit of the security to the Account class, telling that only users with BankAdmin privilege is allowed to do the operations. With this new requirement being added, let us see the modified class structure below.

Account.java

                               
public class Account{
 
    public long deposit(long depositAmount){         
 
        User user = getContext().getUser();
        if (user.getRole().equals("BankAdmin"){              
            newAmount = existingAccount + depositAccount;
            currentAmount = newAmount;
        }
        return currentAmount;
 
    }
 
    public long withdraw(long withdrawalAmount){
 
        User user = getContext().getUser();
        if (user.getRole().equals("BankAdmin"){
            if (withdrawalAmount <= currentAmount){
                currentAmount = currentAmount – withdrawalAmount;
            }
        }
        return currentAmount;
    }   
}
                              

Assume that getContext().getUser() someway gives the current User object who is invoking the operation. See the modified code mandates the use of adding additional if condition before performing the requested operation. Assume that another requirement for the above Account class is to provide some kind of Logging and Transaction Management Facility. Now the code expands as follows,

Account.java

                               
public class Account{
 
    public long deposit(long depositAmount){         
 
        logger.info("Start of deposit method");
        Transaction trasaction  = getContext().getTransaction();
        transaction.begin();          
        try{
            User user = getContext().getUser();
            if (user.getRole().equals("BankAdmin"){          
                newAmount = existingAccount + depositAccount;
                currentAmount = newAmount;
            }
            transaction.commit();
        }catch(Exception exception){
            transaction.rollback();
        }
        logger.info("End of deposit method");
        return currentAmount;
 
    }
 
    public long withdraw(long withdrawalAmount){
 
        logger.info("Start of withdraw method");
        Transaction trasaction = getContext().getTransaction();
        transaction.begin();          
        try{
            User user = getContext().getUser();
            if (user.getRole().equals("BankAdmin"){
                if (withdrawalAmount <= currentAmount){
                    currentAmount = currentAmount – withdrawalAmount;
                }
            }
            transaction.commit();
        }catch(Exception exception){
            transaction.rollback();
        }
        logger.info("End of withdraw method");
        return currentAmount;
 
    }   
}
                               

The above code has so many dis-advantages. The very first thing is that as soon as new requirements are coming it is forcing the methods and the logic to change a lot which is against the Software Design. Remember every piece of newly added code has to undergo the Software Development Lifecycle of Development, Testing, Bug Fixing, Development, Testing, .... This, certainly cannot be encouraged in particularly big projects where a single line of code may have multiple dependencies between other Components or other Modules in the Project.

2.2) The Solution through AOP

Let us re-visit the Class Structure and the Implementation to reveal the facts. The Account class provides services for depositing and withdrawing the amount. But when you look into the implementation of these services, you can find that apart from the normal business logic, it is doing so many other stuffs like Logging, User Checking and Transaction Management. See the pseudo-code below that explains this.

 

 

 

 

                               
public void deposit(){
 
    // Transaction Management
    // Logging
    // Checking for the Privileged User
    // Actual Deposit Logic comes here 
 
}
 
public void withdraw(){
 
    // Transaction Management
    // Logging
    // Checking for the Privileged User
    // Actual Withdraw Logic comes here 
 
}
                               

From the above pseudo-code, it is clear that Logging, Transaction Management and User Checking which are never part of the Deposit or the Service functionality are made to embed in the implementation for completeness. Specifically, AOP calls this kind of logic that cross-cuts or overlaps the existing business logic as Concerns or Cross-Cutting Concerns. The main idea of AOP is to isolate the cross-cutting concerns from the application code thereby modularizing them as a different entity. It doesn't mean that because the cross-cutting code has been externalized from the actual implementation, the implementation now doesn't get the required add-on functionalities. There are ways to specify some kind of relation between the original business code and the Concerns through some techniques which we will see in the subsequent sections.

3) AOP Terminologies

It is hard to get used with the AOP terminologies at first but a thorough reading of the following section along with the illustrated samples will make it easy. Let us look into the majorly used AOP jargons.

3.1) Aspects

An Aspect is a functionality or a feature that cross-cuts over objects. The addition of the functionality makes the code to Unit Test difficult because of its dependencies and the availability of the various components it is referring. For example, in the below example, Logging and Transaction Management are the aspects.

                               
public void businessOperation(BusinessData data){
 
    // Logging
    logger.info("Business Method Called");
 
    // Transaction Management Begin
    transaction.begin();
 
    // Do the original business operation here
 
    transaction.end();
}
                               

3.2) JoinPoint

Join Points defines the various Execution Points where an Aspect can be applied. For example, consider the following piece of code,

                               
public void someBusinessOperation(BusinessData data){
 
    //Method Start -> Possible aspect code here like logging.
 
    try{
        // Original Business Logic here.
    }catch(Exception exception){
        // Exception -> Aspect code here when some exception is raised.     
    }finally{
        // Finally -> Even possible to have aspect code at this point too.
    }
 
    // Method End -> Aspect code here in the end of a method.
}
                               

In the above code, we can see that it is possible to determine the various points in the execution of the program like Start of the Method, End of the Method, the Exception Block, the Finally Block where a particular piece of Aspect can be made to execute. Such Possible Execution Points in the Application code for embedding Aspects are called Join Points. It is not necessary that an Aspect should be applied to all the possible Join Points.

3.3) Pointcut

As mentioned earlier, Join Points refer to the Logical Points wherein a particular Aspect or a Set of Aspects can be applied. A Pointcut or a Pointcut Definition will exactly tell on which Join Points the Aspects will be applied. To make the understanding of this term clearer, consider the following piece of code,

                               
aspect LoggingAspect {}
aspect TransactionManagementAspect {}
                               

Assume that the above two declarations declare something of type Aspect. Now consider the following piece of code,

                               
public void someMethod(){
 
    //Method Start
 
    try{
        // Some Business Logic Code.
    }catch(Exception exception){
        // Exception handler Code
    }finally{
        // Finally Handler Code for cleaning resources.
    }
 
    // Method End
}
                               

In the above sample code, the possible execution points, i.e. Join Points, are the start of the method, end of the method, exception block and the finally block. These are the possible points wherein any of the aspects, Logging Aspect or Transaction Management Aspect can be applied. Now consider the following Point Cut definition,

                               
pointcut method_start_end_pointcut(){
 
    // This point cut applies the aspects, logging and transaction, before the 
    // beginning and the end of the method.
 
}
 
pointcut catch_and_finally_pointcut(){
 
    // This point cut applies the aspects, logging and transaction, in the catch 
    // block (whenever an exception raises) and the finally block.
 
}
                               

As clearly defined, it is possible to define a Point Cut that binds the Aspect to a particular Join Point or some Set of Join Points.

3.4) Advice

Now that we are clear with the terms like Aspects, Point Cuts and Join Points, let us look into what actually Advice is. To put simple, 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.

No comments:

Post a Comment