Results 1 to 4 of 4

Thread: advice ordering doesn't work

  1. #1

    Default 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 at 08:17 AM.

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,624

    Default

    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.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Jun 2006
    Location
    SF Bay Area, California
    Posts
    524

    Default

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

    -Ramnivas
    Ramnivas Laddad (Follow me on Twitter)
    AspectJ in Action: Enterprise AOP with Spring Applications (2nd edition). Now available!

  4. #4

    Default

    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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •