Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Pointcut targeting exercise ...

Hello all,

I have an aspect which should fire only once after any non-default constructor has been executed 
(i.e. after the object has been fully constructed). The purpose is simply to fire a method validating
the internal state within the Entity just constructed. 

a) All non-default constructors
b) The constructor only in the concrete subclass - i.e. not the constructors of all superclasses within the inheritance hierarchy.
c) Only the constructors for (a) and (b) when the type of the class being constructed - or any of its supertypes - implement the Validatable interface as per below.

The pointcut definition below works for [a] and [c] - but it fires for all constructors within the 
inheritance hierarchy of the class being constructed (i.e. after the constructor of the superclass is
executed but before the statements within the constructor of the subclass are executed). 

What have I missed? 
How should the Pointcut _expression_ be to fire only once after the object itself is constructed?


@Aspect
public class ValidationAspect {

    // Our log
    private static final Logger log = LoggerFactory.getLogger(ValidationAspect.class);

    /**
     * Pointcut defining a default constructor within any class.
     */
    @Pointcut("initialization(*.new())")
    void anyDefaultConstructor() {
    }

    /**
     * Defines a Pointcut for any constructor to a class implementing Validatable -
     * except default constructors (i.e. those having no arguments).
     *
     * @param joinPoint    The currently executing joinPoint.
     * @param aValidatable The Validatable instance just created.
     */
    @Pointcut(value = "initialization(com.teliasonera.tindra.core.common.validation.Validatable+.new(..)) "
    + "&& this(aValidatable) "
    + "&& !anyDefaultConstructor()", argNames = "joinPoint, aValidatable")
    void anyNonDefaultConstructor(final JoinPoint joinPoint, final Validatable aValidatable) {
    }

    /**
     * Validation aspect, performing its job after calling any constructor except
     * non-private default ones (having no arguments).
     *
     * @param joinPoint   The currently executing joinPoint.
     * @param validatable The validatable instance just created.
     * @throws InternalStateValidationException
     *          if the validation of the validatable failed.
     */
    @After(value = "anyNonDefaultConstructor(joinPoint, validatable)", argNames = "joinPoint, validatable")
    public void performValidationAfterCompoundConstructor(final JoinPoint joinPoint, final Validatable validatable)
            throws InternalStateValidationException {

… [ code omitted ] …
    }
}

--
// Bästa hälsningar, 
// [sw. "Best regards,"]
//
// Lennart Jörelid, Systems Architect
// cell: +46 708 507 603
// skype: jgurueurope


Back to the top