Mohan Radhakrishnan has posted a great article called Writing Mixins using AspectJ. The article outlines a way to add PropertyChangeSupport
to a POJO using AspectJ 5. It’s very similar to the JavaBean Aspect (Now known as the “ValueBean Aspect”) I posted a while back. This is really great because I have been trying to figureout how I can get the ValueBean Aspect working under AspectJ5. In reading this article, I was hoping to find some solutions to the challenges I’ve encountered while trying to do this. Like the JBoss AOP version, I hoped to make thePropertyChangeSupport
available to all setters in a bean marked with the @ValueBean
annotation. Having to mark each field with the @propertyChanger
annotation kinda defeats the purpose in my opinion.
In regards to Mixins and Introductions, I find that JBoss AOP to make things a tad easier. For example, introducing the ValueBeanMixin
is relatively simple:
... @Introduction(typeExpression = "class(@com.damnhandy.aspects.bean.ValueBean)", interfaces = { ValueBeanSupport.class }) public static Object javaBeanIntroduction; @Mixin(typeExpression = "class(@com.damnhandy.aspects.bean.ValueBean)", interfaces = { ValueBeanSupport.class }) public static ValueBeanMixin createJavaBeanMixin(Object obj) { return new ValueBeanMixin(obj); } ...
And with that, any class marked with a @ValueBean
annotations will now have PropertyChangeSupport
. I thought that anAspectJ 5 Version of this might look something like:
declare parents : @ValueBean * implements ValueBeanSupport;
But that doesn’t quite work, and this is where problem #1 comesin: Mixins need both an interface and an implementions class to back them. Mohan’s PropertySupportAspect
seems to work the concreteBean
class and not simply any class marked with an@javaBean
annotation. What makes matters more complicated is that the AspectJ 5 Development Notebook states: “Anannotation type may not be the target of an inter-type declaration.” Hopfully I’m not reading that correctly, or I misundertand the context.So making the introduction to an annotated class in AspectJ 5 is still amystery to me.
My next challenge is to ensure that thePropertyChangeAspect
is only applied to classes marked with the @ValueBean
annotation. In Mohan’s example, the pointcut doesn’t check to see if the Bean,
class is marked with the @javaBean
annotation. By just checking the methods with a @propertyChanger
annotation, you don’t gurantee that the advised class provides support for bound properties. In the JBoss AOP version of the ValueBean Aspect, I define the following pointcut for thePropertyChangeAspect
:
@Bind(pointcut="set(* @com.damnhandy.aspects.bean.ValueBean->*) " + "AND !withincode(@com.damnhandy.aspects.bean.ValueBean->new(..)) " + "AND !field(*@com.damnhandy.aspects.bean.ValueBean-> @com.damnhandy.aspects.bean.NotBound)")
This pointcut traps any FieldWriteInvocation
on a field within a class marked with the @ValueBean
annotation. It also ignores and field values which are set within the constructor ofthe class and fields that are marked as @NotBound
. With AspectJ 5, I have tried achieve the 1st part of the same pointcut usingthe following:
pointcut valueBeanSetter(ValueBean bean): execution( void set*(..)) @target(bean); void around(ValueBean bean) : valueBeanSetter(bean) { ...
The around advice is then applied to every setter in every class, regardless of whether or not the @ValueBean
is present. Obviously, I still have a lot more research to do on Aspect J 5, but if anyone has any pointers or tips on the topic, I’d appreciate it!