Announcement Announcement Module
Collapse
No announcement yet.
advice ordering doesn't work Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • advice ordering doesn't work

    Hello there!

    I'd like to utilize the ordering of multiple aspects on one joinpoint. But the @Order annotation nor using "implement Ordered" and setting an "int order;" value seems to affect the order of the invocation of the aspects.

    I've tried following simple program/setup to magage this:

    A concurring joinpoint is on the inc function of following Increment class:
    Code:
    public class Increment {
    
        private static Logger logger = Logger.getLogger(Increment.class);
    
        public int inc(int value) {
            logger.debug ("before inc");
            return value++;
        }
    }
    There are two aspects - Aspect 1:
    Code:
    @Aspect
    @Order(value = 2)
    public class Aspect1 {
    
        private static Logger logger = Logger.getLogger(Aspect1.class);
    
        @Around("execution(* Increment.*(..))")
        public Object interception1(ProceedingJoinPoint pjp) throws Throwable {
            try {
                logger.debug("Aspect1 before");
                Object ret = pjp.proceed();
                logger.debug("Aspect1 after");
                return ret;
            }
            catch (Throwable e) {
                logger.debug("there was an error!" + e.toString());
                throw e;
            }
        }
    }
    and the Aspect 2 (quite similar):
    Code:
    @Aspect
    @Order(value = 1)
    public class Aspect2 {
    
        private static Logger logger = Logger.getLogger(Aspect2.class);
    
        @Around("execution(* Increment.*(..))")
        public Object interception2(ProceedingJoinPoint pjp) throws Throwable {
            try {
                logger.debug("Aspect2 before");
                Object ret = pjp.proceed();
                logger.debug("Aspect2 after");
                return ret;
            }
            catch (Throwable e) {  
                logger.debug("there was an error! " + e.toString());
                throw e;
            }
        }
    }
    the applicationContext.xml has following content:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
    
        <bean id="incrementId" class="at.elements.tests.aop.Increment"/>
        <aop:aspectj-autoproxy/>
    </beans>
    for completeness here's the Main
    Code:
    public class Test {
    
        private static Logger logger = Logger.getLogger(Test.class);
    
        public static void main(String args[]) {
    
            PropertyConfigurator.configure("log4j.properties");
            ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
            Increment increment = Increment.class.cast(context.getBean("incrementId", Increment.class));
    
            int result = increment.inc(1);
            logger.debug("result of inc(1)=" + result);
    
        }
    }
    I'm using maven to compile this tiny project and used the following dependencies (snippet):
    Code:
    <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring</artifactId>
                <version>2.5.5</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>1.6.6</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.6.7</version>
            </dependency>
        </dependencies>
    Whatever values for the order is set - the interception of Aspect2 is always executed at first. In the example above, I think, interception1 should be executed first - but the result is the following (interception2 is executed first):
    Code:
    [main] DEBUG Aspect2 - Aspect2 before
    [main] DEBUG Aspect1 - Aspect1 before
    [main] DEBUG Increment - before inc
    [main] DEBUG Aspect1 - Aspect1 after
    [main] DEBUG Aspect2 - Aspect2 after
    [main] DEBUG Test - result of inc(1)=1
    I'd loved to be advised what I'm doing wrong here.
    Thanks a lot!
    Last edited by meisterlampe; Feb 12th, 2010, 08:17 AM.

  • #2
    Your aspects aren't defined in your xml file and aren't applied unless you use AspectJ compile time weaving but that doesn't understand @Ordered.

    Comment


    • #3
      You need to use @DeclarePrecedence to control ordering of aspects. Check AspectJ documentation for more details.

      -Ramnivas

      Comment


      • #4
        simply defining the Aspects1&2 classes in the xml worked out!
        next, i was missing the cglib dependency.

        thanks a lot!

        @ramnivas:
        i'm looking forward to see what the @DeclarePrecedence is - as you may suppose, i'm really new to aop
        is this a more gentle way to do this?

        finally, i'll intercept hibernate exceptions thrown from @Transaction annotated methods. i've already tried out but the ordering didn't worked and so tried the above example. for the transaction-management i'll use the order property:

        <tx:annotation-driven transaction-manager="transactionManager" order="3"/>

        -meisterlampe

        Comment

        Working...
        X