Today at Amazon we have Russell Miles, author of the AspectJ Cookbook. Russ is the latest speaker in our Friday Learning Series, an internal continuing education program for our developers.
Russ will talk about why we should be doing Aspect-Oriented programming.
- What is AOSD and why is it important?
- Key features of AOSD
- Advanced features of AspectJ
- Types and scales of Aspect
- Refactoring for AO
- AO Challenges
- Where is AspectJ and AO going?
What is AOSD? It is not just for logging and tracing, there are many scenarios where it can be used. He'll cover theory and then practice.
Let's start with software concerns. A concern is a goal, concept, or area of interest (Laddad). A system is made up of a collection of concerns.A concern is a collection of behavior and data. There are two types of concerns, core and cross-cutting. The aarchitect's dilemma is to take into account future change while not creating an overdesigned system. Be sure to developer something, don't sit around and think too much.
What's wrong with object orientation? Some concerns don't work within current OO approaches. Problematic concerns cross-cut an application. Lack of modularization of cross-cutting results in code tangling, code scattering, and duplication. AO tries to manage and solve this problem.
Diagram of an analysis of an XML parser, indicates where a particular concern is used within the code. This code has good modularity. Related areas are well encapsulated. Changes have a minimal ripple effect. The graphs were drawn using the AspectJ toolkit component of Eclipse. Another diagram, this one of logging within Tomcat. It is all over the place, and not even in a small number of places. OO practices can lead to bad modularity for certain types of concerns.
Bad modularity leads to redundant code, difficult to reason about structure (because it is not explicit), difficult to change ("nightmare").
Example of some Java code. Class with a method. Add some logging of start and completion, adds code to beginning and end of method, and add an attribute to the class. This has nothing to do with the requirements for the class. Now add a new requirement, thread safety. Again, adds more code, lock/unlock. Then add constraint for programming by contract, then authorization, persistence, cache consistency, and so forth. Lots of stuff that is unrelated to, yet complicating, the class. Core operation is almost hidden.
Aspect Orientation (AO) to the rescue. Modularize across concerns, rules for where it is going to be applied as well as what is to be done. Needs language or framework support in order to do it right.
Other languages: #define (C/C++, C#). Manually declared, not modular,not AO. Source-level metadata: annotations in Java, C#. Again, must be declared on code block. Not modular and not AO.
Question: What about debugging? Answer: IDE and tool support is important.
Enter AspectJ. A small extension to Java, a first-class language extension. Supports three core AO models: Aspects, Pointcuts, and Advise.
More Java code, 1 class and 3 methods. Eclipse, create Aspect, for logging. aspect is new keyword for Java.
Join points - a discrete point in the application that can be captured. Method calls, exception handling, object creation.
Aspects - First class language construct. Can be declared abstract. Aspect is modularization for AO. Can contain traditional Java attributes and methods. There can be complex relationships between Aspects. Aspects have lifecycles and can have relationships-- inherit from other classes or aspects, implement interfaces, declare classes, declare aspects. Lifecycle is not managed by developer.
Aspect lifecycles can be singleton, perthis(Pointcut) pertarget(Pointcut), or percflow() (control flow), lives for duration of control.
Pointcuts - encapsulate the 'where'. Based on pointcut logic. Can use wildcards, can be anonymous or named, and can be abstract. Many types: call, execution, handler, initialization, static initialization, get, set, within, adviceexecution. Putting them on accessors can be done, but appears to be bad practice. All pointcuts are scoped. Execution and call are good pointcuts to use.
Can combine pointcuts using logic, &&, || , ! (not). Don't join on stuff you are not interested in.
Advice - Encapsulate the 'what'. Unnamed and local to an Aspect. Never abstract. Five types: before, after, around after returning, and after throwing. Around lets you override a constructor and return a different object. Multiple advice per join point.
Java example: Use methodCalled advice to implement logging. Goal is to make this all as transparent as possible. Advice can use wildcards on callers and types to choose what they apply to.
Recommendation: Optimize and tune as much as possible. Use AspectJ Visualizer to see coverage.
Any runtime or compile time info available at join point is available to the Advice code.
On to AspectJ. Heavyweight language, extension to Java. Power extensions; use them with care. Support for static cross-cutting to alter application architecture, changes how application is put together. Don't use it to fix bad code or bad design. Use when you need new values or behavior in an existing app, such as in the implementation of an Observer pattern. Advise and extend the compiler to declare warnings and errors, create your own rules. Could use it to deprecate things, "but very strongly."
Use the Director design pattern.
Question: How does this work? It looks like magic!
Answer: It uses another compiler, a pre-compiler to the regular Java compiler. There's also something called aspect weaving, which apparently happens at the byte code level.
Question: Does Reflection give AspectJ conniptions?
Answer: Yes, it can be, and you can implement a lot of what AspectJ does, without modularity.
Scales of Aspect:
- Class and component - parameter validation, class persistence
- Application - logging, lazy loading
- Enterprise - transactions, security policy
Aspects can be declared public and static, within a class, to enforce invariants using an around() advice item. Must be public so that the AspectJ runtime can see the code.
Refactoring for AO, a relatively new area, a new book is on the way. Migrating to AO requires refactoring.
Impact of AO on OO. Change of perspective, help for the architect's dilemma. Increase controlled flexibility. Provides benefits to some OO design patterns.
There are some design patterns in AO, mostly just starting to emerge. Include Cuckoo's Egg, Director, and Worker Object. This is all work in progress.
Challenges: Learning curve, IDE support (Eclipse, JBuilder, NetBeans). Other languages still to come. Modeling and design are not yet supported in tools. Methods and practices are starting to appear. AOSD with Use Cases.
Where is it going? AspectJ 5.0 on the way. J2SE 5.0 support, Annotation Join Points, Annotations within Aspects, Generics and Join Points, aUnit for testing.
Summary: We've seen the power of AO through examples, still need to dispel some myths:
- Program flow is hard to follow - true
- Doesn't solve any new problems - true
- Promotes sloppy design - false
- Nice interface but abstract OOP is all that's needed - false
- Breaks encapsulation - true, partial remedy is requirement to declare aspects as privileged.
- AOP will replace OOP - false
Q: Performance Setbacks?
A: Not supposed to be, really depends on implementation of language. Should be same as hand coding of what the aspects do.Before & after are better than around. Use it for the right reasons.
Q: One join point and several aspects, what happens?
A: There's a precedence, set on the aspect.
Q: Assuming there will be libraries of aspects, what's the precedence?
A: You can declare precedence outside of the aspect, to set this.
Q: Besides logging, what are other generic aspects?
A: (reads from the book), transactions, locking, exception handling, any characteristic that doesn't seem to fit into the class, shouldn't be there.
Q: Transactions and nesting, how?
A: There's an example online (to be supplied).
Q: Can you create a chain of responsibility between aspects?
A: Yes, I'll get you an example.
Q: Any performance profiling written in AspectJ?
A: Yes, this is a good way to analyze a base of software.
Q: Aspect interaction with threads?
A: Threads are just like every other piece of code, make sure that the advice code is thread-safe. Use standard language protection mechanisms.