Announcement Announcement Module
No announcement yet.
Using multiple annotations/aspects on the same method Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using multiple annotations/aspects on the same method


    [ All java files and app context at the end of this post ]

    I'm new to AspectJ / Spring AOP and having problems when applying multiple annotations against a method. Also thinking of using Spring Integration for a project and assessing error handling features.

    I have the following test "pipeline" scenario:

    JMS Q --> Spring I. JMS Msg Driven Adapter --> direct channel --> Transformer --> direct channel --> Service Activator (a dummy validator object).

    The code attached places 2 msgs on the JMS Q that ripples throught the pipeline channels. The first succeeds, the 2nd fails (hard-coded Exception thrown) so that I can test out my aspects are working correctly.

    Actual project will have a succession of about 7/8 channels each with an Endpoint.

    Noticed that if there's at least one pollable queue in the chain of channels you get generic error handling for free and can capture the failed msg using MessagingException.getFailedMessage() etc etc. That's nice, however, with a sequence of direct channels only, the failed msg isn't sent to the generic errorChannel, as the Exception is propagated back to the sender. In my case, the Exception propagates back to the JMS Msg driven adapter.

    To remedy this I'm going to use an "aspect / bespoke annotation" approach e.g. (@PipelineExceptionHandlingRequired) and annotate any method that requires an exception to be caught and direct the failed Message to an error channel. The Aspect then looks out for any methods that fire with this annotation and see if an Exception is thrown if it is I send a msg to a channel: "myErrorChannel".

    I apply the PipelineExceptionHandlingRequired annotation to the Validator.validate() method.

    This seems to work OK (although I'm not sure my method of trapping the exception in the ProceedingJoinPoint is the correct approach - can anyone help on that?)

    I also want to introduce another annotation to the same method Validator.validate() so that I can record the time when the validate() method successfully completes.

    To handle this requirement I introduce another bespoke annotation called @PipelinePersistencePoint and have an associated Aspect to handle the processing.

    My problem is that when I place both annotations together on a method (as below) the aspect associated with @PipelineExceptionHandlingRequired doesn't seem to think an Exception has been raised when I execute ProceedingJoinPoint.proceed() so no exception gets thrown.

    Validate method:
    @PipelineExceptionHandlingRequired(propagateExcept ion=true, pipeLineContext="Validator", errorChannel="myErrorChannel", retryChannel="validatedTrades")
    @PipelinePersistentPoint(persistencePointName="Val idator", persistenceChannelName="persistencePointChannel")
    public void validate(Message<PipelineMessage> msg) throws Exception {
    If I remove the PipelinePersistentPoint annotation from the validate() method , the Aspect associated with the PipelineExceptionHandlingRequired annotation works again.

    All code attached in ZIP file + Maven POM file attached for a project named 'mvntest'.

    Any help really appreciated.


  • #2
    I've simplified my approach above and answered my question - having multiple around-aspects against a single method is possible and won't execute the "validate" method below more than once.

    Anyone know what the performance hit is by doing this - extra Spring proxy objects per aspect?

    I now have 3 annotation driven aspects with associated pointcut/aspects for a method:


    public void validate(Message<PipelineMessage> msg) throws Exception {

    The first is an around aspect that does X if no expection, Y if exception raised.
    The second is a similar around aspect does A if no expection, B if exception raised.
    The third is an after-throwing aspect to specifically deal with exceptions.

    I'm using the above approach to monitor Endpoint message handlers used in Spring Integration