Thursday, October 16, 2008

Aspect Oriented Programming - Is it black magic?

When first exposed to AOP a rush of potential application occurs, the possibilities where intoxicating. A myriad of possibly utilities come to mind with the ability to transparently apply logic (advice in AOP terminology) to instance creation, method calls, variable initialization (joint points in AOP).

Frameworks and approaches have been around for a while that allows instrumentation of Java bytecodes usually used for peformance profiling or applying the "proxy" design patterns implementations. AOP does this with a formal declartive programming language, making its application less technical allowing it to be applied safely, easily, and transparently.




AOP was developed around the mid-ninties to help with modularization. OO based languages were promising reuse and lego building block type productivity, but functionality that cut across modular boundaries such as logging, transaction and security was standing in the way of reuse. With OO you can deliver a generalized abstract solution for a problem space. Users of this solution can apply it an access it's various methods in arbitrary fashion providing much utility. Consider a generalized purchase order PDF component/framework specific for a purchasing sytem. Users can apply this framework by extending from classes or implementing interfaces and calling public API methods. This framework can then be reused and embedded in applications with other frameworks, components, and custom code to form an end user solution. However, we want to just reuse the PDF purchasing component and may not have source, nor the desire to change component source code. This is where AOP technology comes into play. With AOP allows interception of method calls, instance creation, or variable assignment and the ability to apply advice (logic) to these interceptions (join points).
that generali but a problem arises when this solution is put into use. requires different transaction demarcation boundaries or security privleges. Each use of the solution requires different access paths that are determined by how the solution is used.

Why AOP?

AOP is a product of early researchers to solve the modularity problem of object oriented software development. OO languages have most of the constructs available such as inheritence, polymorphism, and information hiding that allows for resuable components to be defined that can be configured and exercises in a black box type of way to solve a problem. However, objects making up a framework of component boundary will invariable have to integrate other reusable components/frameworks (ala Log4J), or apply some kind of logic (security/transactions) that cannot be predicted across implementation along with creating usage and framework dependencies. AOP allows things like logging and security to be applied to solutions from outside the code, allowing developers to write source code purley for a specific domain solution. AOP proramming is applied in the context of how your component(s) need to be used, therefore promoting more reuse, removing depedencies, and providing cleaner code.


Quick Primer


There'a a lot to AOP, but here's a quick primer that will hopefully help with general understanding. An Aspect is the programming element you want to apply. For instance a Logging aspect will apply logging. The example below is a logging aspect defined for the Spring AOP framework. The annotations and special method signature makes this an Aspect. There are other AOP frameworks AspectJ, AspectWerkst to name a couple. AspectJ can be used as a stand alone solution and it provides much broader ability to apply AOP. With Spring AOP you can only apply aspects to methods visible to the application context. AspectJ AOP allows aspects to be applied to any method, property, instance creation, or thrown exception.



Where an annotation is applied is determined by a Pointcut which is an AOP way to specify where an annotation should be applied. In the case of Spring AOP aspects can be applied to a classes method execution point during runtime, which can be, before, during, or after. This is defined using general or specific method signature patterns that can be wildcarded so that an aspect can be targeted towards specific method(s). An example Spring AOP pointcut definition is shown below that apply and Aspect to all instance methods to classes defined in the service package. The example shown below is a Spring annotation based Aspect that will log all method calls to anything matching the controller class package specified by the @Before pointcut annotation.



@Aspect
public class Logger {


@Before("execution(* com.*.controller.*.*(..))")
public Object logController(JoinPoint call) throws Throwable {


Log log = LogFactory.getLog(call.getTarget().getClass());
log.info("WM-CONTROLLER EXECUTION:" + call.getTarget().getClass() + "." + call.getSignature().getName());
return null;


}

}



How to Adopt

You can become familiar safley apply AOP by using to to support debugging and performance tuning tasks. For example create a logging example that reports method execution timings, yuo can easily apply logic that senses for methods where most time is spent. Once you become mreo comfortable you can defined aspects that will support production implementations. These could include aspects apply object caching, or apply security and transactions behaivor. Don't use AOP to apply or control business logic, as tempting as it may be this kind of misues may seem state of the art, but instead coul lead to hard to maintain and fragile source code.

No comments: