This post originated from an RSS feed registered with Java Buzz
by Geoffrey Wiseman.
Original Post: Aspect and Annotation Symbiosis
Feed Title: Furious Purpose
Feed URL: http://www.jroller.com/diathesis/feed/entries/rss
Feed Description: Thoughts and experiences on technology and software.
Although attributes and aspects have often seemed like a pair with a lot in common,
reading the AOP@Work article AOP
and metadata: A perfect match
really started to make the two sides gel in my imagination.
Deciding where to apply aspect advice has always seemed a little messy to me; having
to do things like regular expression method name matchers is effective, but not very
natural. Applying advice based on aspects makes a lot more sense to me, and ends up
feeling very natural.
Problem: AOP Transactional Service Layer
I ran into a problem a few days back. We've chosen to apply a transactional boundary
(using Hibernate, Spring and AOP) around the service layer. When a service method
returns, the transaction commits. Pretty standard stuff.
In some cases, we want to use the primary key from a new object in the return value.
This is slightly irritating since the transaction hasn't committed, but if we save
the object explicitly, Hibernate will give us a key, and the problem is solved again.
However, this gets worse when you want keys not only for a single class but for,
potentially, an object graph. If you save the root of the graph, Hibernate seems
to get you a key for the root, but doesn't bother to process the cascades, presumably
because the transaction hasn't committed. I've done a little digging in SessionImpl
and returned none the wiser. SessionImpl is impenetrable to a quick look, so I may
have to return another time and spend more time with it.
I wasn't extremely comfortable with the idea of saving each child object manually,
so, upon consideration, what seemed to make the most sense was this: commit the
transacation before the service method returns.
Unfortunately, that didn't match our current aspect enhancement model.
A Solution: Borrowing from EJB
Happily, between the EJB syntax and the AOP@Work article, it occurs to me that
what I really wanted was this:
// service method
@Transactional(mode=Supports)
public Object getObjectGraph() { return createObjectGraph(); }
// internal helper
@Transactional(mode=RequiresNew)
public Object createObjectGraph() { ... }
In this case, createObjectGraph creates the objects, an aspect attached to @Transactional
will, after examining the mode, wrap the method with a transaction which will have closed
by the time the method returns to getObjectGraph(), which can now return the graph with
all keys fully attached.
Problem: AOP Documentation
Another problem that has surfaced in recent uses of AOP is that of documentation, both
in the form of source documentation and generated documentation in the form of Javadoc.
To the eye of a user familiar with Java but not with aspects, an enhanced class can be
confusing. A class that requires authentication has no authentication documentation,
because the authentication is verified by an aspect. A class that requires authentication
has no visible authentication code.
public class UserManagementService
{
/** Creates a user */
public createUser();
}
Annotations seem like they can help with both:
public class UserManagementService
{
/** Creates a user */
@VerifyAuthentication(role=Role.ADMIN)
public createUser();
}
Not only does the annotation supply a visual cue to a developer that something more
may be happening underneath the surface, but, from a quick examination of the changes
to Javadoc in J2SE 5, it looks as you could jump from the annotated method to the
annotation and, from there, to a custom tag on the annotation to apply additional
documentation. This would allow you to add documentation to the Javadoc of any
enhanced methods.
/**
* Annotation for verifying authentication.
*
* @enhancement verifies authentication using the supplied role before allowing
* access to the method under enhancement
*/
public @interface VerifyAuthentication
{
...
}
While both aspects and attributes have their own benefits and disadvantages, I'm
inclined to think that annotations will play an increasingly useful role in the
world of aspects. I'm looking forward to it.