Introduction to Aspect-Oriented Programmingby Graham O'Regan
Overview of Aspect Oriented Programming
When Object-Oriented (OO) programming entered the mainstream of software development, it had a dramatic effect on how software was developed. Developers could visualize systems as groups of entities and the interaction between those entities, which allowed them to tackle larger, more complicated systems and develop them in less time than ever before. The only problem with OO programming is that it is essentially static, and a change in requirements can have a profound impact on development timelines.
Aspect-Oriented Programming (AOP) complements OO programming by allowing the developer to dynamically modify the static OO model to create a system that can grow to meet new requirements. Just as objects in the real world can change their states during their lifecycles, an application can adopt new characteristics as it develops.
Consider an example: many of you have developed simple web applications that use servlets as the entry point, where a servlet accepts the values of a HTML form, binds them to an object, passes them into the application to be processed, and then returns a response to the user. The first cut of the servlet may be very simple, with only the minimum amount of code required to fulfill the use case being modeled. The code, however, often inflates to three to four times its original size by the time secondary requirements such as exception handling, security, and logging have been implemented. I use the term "secondary requirements" because a servlet should not need to know about the logging or security mechanisms being used; its primary function is to accept input and process it.
AOP allows us to dynamically modify our static model to include the code required to fulfill the secondary requirements without having to modify the original static model (in fact, we don't even need to have the original code). Better still, we can often keep this additional code in a single location rather than having to scatter it across the existing model, as we would have to if we were using OO on its own.
In this article, we will look at a simple application that will hopefully allow you to see the benefits of AOP firsthand, and then we will briefly discuss how AOP could be used in your existing projects.
Before we delve too deeply into AOP, let's introduce some standard terminology to help us understand the concepts.
Cross-cutting concerns: Even though most classes in an OO model will perform a single, specific function, they often share common, secondary requirements with other classes. For example, we may want to add logging to classes within the data-access layer and also to classes in the UI layer whenever a thread enters or exits a method. Even though the primary functionality of each class is very different, the code needed to perform the secondary functionality is often identical.
Advice: This is the additional code that you want to apply to your existing model. In our example, this is the logging code that we want to apply whenever the thread enters or exits a method.
Point-cut: This is the term given to the point of execution in the application at which cross-cutting concern needs to be applied. In our example, a point-cut is reached when the thread enters a method, and another point-cut is reached when the thread exits the method.
Aspect: The combination of the point-cut and the advice is termed an aspect. In the example below, we add a logging aspect to our application by defining a point-cut and giving the correct advice.
There are many other facets of AOP, such as introductions (where interfaces/methods/fields can be added to existing classes), that hold tremendous potential for developers, but I'll stick with some of simpler facets in this article. When you are familiar with the concepts presented here, I would recommend that you continue to investigate AOP and see how the other facets may be of use to you in your development environment.
Probably the most mature and fully featured framework available today is AspectJ. While AspectJ sets the standard that most frameworks follow, the architects took the unusual step of adding new keywords to the Java language in their implementation. Though the new syntax isn't too difficult to learn, it does mean that you will have to change your compiler, and potentially reconfigure your editor, in order to use the new syntax. In a large team this may not be feasible, as the whole team could be affected. The modification to the language also increases the learning curve for teams looking to introduce AOP into existing projects.
What we need is a framework that can be easily introduced without severely impacting the existing development and build process. There are several frameworks that fit the bill, such as JBoss AOP, Nanning, and Aspectwerkz (AW). For this article, I've chosen Aspectwerkz because it is probably the easiest framework to learn and integrate into your existing projects.
Aspectwerkz, created by Jonas Boner and Alexandre Vasseur, remains one of the quickest and most fully featured AOP frameworks available. While it may not boast all of the features of AspectJ, it is sufficiently complete to be of great use to most developers in many situations.
One of the most interesting features of Aspectwerkz is its ability to run in two different modes: online
and offline. In online mode, AW is hooked into the low-level classloading mechanism part of the JVM, allowing it to intercept all classloading calls and transform the bytecode on the fly. AW provides many
options to hook in, and a wrapper script can be used as a replacement for the
bin/java command to automatically detect and set a working configuration depending on the Java version and JVM capabilities. This mode holds many benefits to developers, as it can be hooked into any classloader and weave classes at classload time, which means that your class files are not modified manually, but deployed as usual. However, it
does require additional configuration of your application server, which may not be possible in some situations.
In offline mode, two phases are required to generate your classes. The first phase is the standard compilation
javac tool that we all know and love. (In fact, most of us love it so much that we
replaced it with an Ant task years ago.) The second phase is where things get interesting, we run the AWcompiler in offline mode and point it to the newly created class files. The compiler will then modify the bytecode of the classes to include your advice at the correct point-cuts, as defined in an XML file. The benefit of using the offline mode is that the classes will run in any JVM from version 1.3 and up. This is the mode that I will
use in this article, as it requires no modifications to Tomcat and could be applied to most existing projects with only slight modification to the build process.
In this article, we are going to write look at a simple application,
compile it using Ant, and deploy it on a Tomcat 4+ servlet container. I am going to assume that you have already installed the above, along with a JVM 1.3+, and that your Tomcat installation is set to deploy
applications from the webapps folder automatically and expand the WAR
files into directories (this is the default behavior, so if you haven't
modified Tomcat, this application should work out of the box). We will
refer to the location where Tomcat is installed as
Download Aspectwerkz from its web site and extract the compressed file to your preferred location. We'll refer to this location as
Add the Aspectwerkz compiler to your
PATHenvironment variable; i.e.,
Download the sample application that accompanies this article and drop it into your %TOMCAT_HOME%\webapps folder.
Add the Aspectwerkz runtime classes to Tomcat's classpath. You could drop the JAR files from %ASPECTWERKZ_HOME%\lib into the WEB-INF\lib folder of the sample application, or into %TOMCAT_HOME%\common\lib.
Pages: 1, 2