It is found, many programming problems for which neither procedural nor object-oriented programming techniques are sufficient to clearly capture some of the important design decisions the program must implement.
Object-oriented programming (OOP) has been presented as a technology that can fundamentally aid software engineering, because the underlying object model provides a better fit with real domain problems. But we have found many programming problems where OOP techniques are not sufficient to clearly capture all the important design decisions the program must implement. Instead, it seems that there are some programming problems that fit neither the OOP approach nor the procedural approach it replaces.
Aspect-oriented programming entails breaking down program logic into distinct parts (so-called concerns, cohesive areas of functionality). All programming paradigms support some level of grouping and encapsulation of concerns into separate, independent entities by providing abstractions (e.g. procedures, modules, classes, methods) that can be used for implementing, abstracting and composing these concerns. But some concerns defy these forms of implementation and are called crosscutting concerns because they "cut across" multiple abstractions in a program.
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.
Features of AOP:
1. 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.
2. 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.
3. 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.
4. 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.
5. Target object: object being advised by one or more aspects. Also referred to as the advised object. Since Spring AOP is implemented using runtime proxies, this object will always be a proxied object.
6. AOP proxy: an object created by the AOP framework in order to implement the aspect contracts (advises method executions and so on). In the Spring Framework, an AOP proxy will be a JDK dynamic proxy or a CGLIB proxy.
7. Weaving: linking aspects with other application types or objects to create an advised object. This can be done at compile time (using the AspectJ compiler, for example), load time, or at runtime. Spring AOP, like other pure Java AOP frameworks, performs weaving at runtime.
When thinking of an object and its relationship to other objects we often think in terms of inheritance. We define some abstract class; let us use a Dog class as an example. As we identify similar classes but with unique behaviors of their own, we often use inheritance to extend the functionality. For instance, if we identified a Poodle we could say a Poodle Is A Dog, so Poodle inherits Dog. So far so good, but what happens when we define another unique behavior later on that we label as an Obedient Dog? Surely not all Dogs are obedient, so the Dog class cannot contain the obedience behavior. Furthermore, if we were to create an Obedient Dog class that inherited from Dog, then where would a Poodle fit in that hierarchy? A Poodle is A Dog, but a Poodle may or may not be obedient; does Poodle, then, inherit from Dog, or does Poodle inherit from Obedient Dog? Instead, we can look at obedience as an aspect that we apply to any type of Dog that is obedient, as opposed to inappropriately forcing that behavior in the Dog hierarchy.
In software terms, aspect-oriented programming allows us the ability to apply aspects that alter behavior to classes or objects independent of any inheritance hierarchy. We can then apply these aspects either during runtime or compile time.
Aspect Oriented Programming and Java
AOP is a concept, so it is not bound to a specific programming language. In fact, it can help with the shortcomings of all languages (not only OO languages) that use single, hierarchical decomposition. AOP has been implemented in different languages (for example, C++, Smalltalk, C#, C, and Java).
Of course, the language that gains a great interest of the research community is the Java language. The following is a list of tools that support AOP with Java:
- AspectJ
- AspectWerkz
- Hyper/J
- JAC
- JMangler
- MixJuice
- PROSE
- ArchJava
AspectJ, created at Xerox PARC, was proposed as an extension of the Java language for AOP. The rest of this article is related to AspectJ terminology.
The term “Spring AOP” is now being very popular by time. It is implemented in pure Java. There is no need for a special compilation process. Spring AOP does not need to control the class loader hierarchy, and is thus suitable for use in a J2EE web container or application server.
Spring AOP currently supports only method execution join points (advising the execution of methods on Spring beans). Field interception is not implemented, although support for field interception could be added without breaking the core Spring AOP APIs. If you need to advise field access and update join points, consider a language such as AspectJ.
Aspect Oriented Programming and .NET:
AOP is accomplished in .NET by having Aspect code insert itself and participate in the message-invocation mechanism that takes place between a client and an object. The private Context set up by the .NET runtime for an instance of a ContextBoundObject provides the means for externally defined Aspects to hook into the call chain, because the creation of the private Context forces the creation of .NET proxies. These proxies provide the means for Aspects to hook into the call-chain using message sinks. The reason that ContextBoundObject is required is for clients and objects that are in the same AppDomain that would otherwise have no proxies set up between them. Aspects are thus implemented as event sinks that get called on the message sink chain without any further participation or knowledge on the client’s part. Some important parts of it are:
- Instances of ContextBoundObject are always associated with a Context.
- A Context can have zero or more properties which are instances of IContextProperty.
- The properties are created and added to the Context by custom attributes that annotate the ContextBoundObject. These custom attributes must be instances of IContextAttribute.
- A context-property can also perform the role of a message sink factory by implementing one or more of the four interfaces, namely, IContributeEnvoySink, IContributeClientContextSink, IContributeServerContextSink, and IContributeObjectSink. A message sink is an instance of IMessageSink
- Access to a ContextBoundObject is always intercepted by the CLR using proxies and message sinks. A message sink is inserted into the invocation chain by the CLR during object activation and can inject the desired aspect at runtime.
The complexity in some existing code is traced to a fundamental difference in the kinds of properties that are being implemented. Components are properties of a system, for which the implementation can be cleanly encapsulated in a generalized procedure. Aspects are properties for which the implementation cannot be cleanly encapsulated in a generalized procedure. Aspects and cross-cut components cross-cut each other in a system’s implementation. We have been able to develop aspect-oriented programming technology that supports clean abstraction and composition of both components and aspects. The key difference between AOP and other approaches is that AOP provides component and aspect languages with different abstraction and composition mechanisms. A special language processor called an aspect weaver is used to coordinate the co-composition of the aspects and components.
The AOP conceptual framework will be helpful to design the systems, and the AOP-based implementations have proven to be easier to develop and maintain, while being comparably efficient to much more complex code written using traditional techniques.