I have one advice which changes the method argument. I have another advice which just prints the argument. The first advice successfully changes the method arguments, but the second advice does not see the changed argument. It only sees the original arguments. Is it possible for the second advice to see the argument changes made by first advice?
I have @Order on both aspects so that the first advice executes before the second advice. I am using Spring with AspectJ LTW.
Here is the code:
the bean which is advised:
The first annotation and it's advice:Code:package com.test; public class MyBean { public void update(String str) { updateStr(str); } @UpdatePrint @ReplaceString private void updateStr(String str) { doSomethingwithStr(str); } private void doSomethingwithStr(String str) { System.out.println("doSomethingwithStr: " + str); } }
This is the second annotation and it's advice:Code://ReplaceString.java package com.test; import java.lang.annotation.Target; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ReplaceString { } //ReplaceStringAspect.java package com.test; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.core.annotation.Order; @Aspect @Order(1) public class ReplaceStringAspect { @Around("execution(* *(..)) && @annotation(ReplaceString)") public Object logPrint(ProceedingJoinPoint pjp) throws Throwable{ Object[] args = pjp.getArgs(); String str = (String) args[0]; args[0] = str + "TWO."; System.out.println("## Start ReplaceStringAspect. str=" + args[0]); Object retVal = pjp.proceed(args); System.out.println("## Done ReplaceStringAspect. str=" + args[0]); return retVal; } }
This is the beans file:Code://UpdatePrint.java package com.test; import java.lang.annotation.Target; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface UpdatePrint { } //UpdatePrintAspect.java package com.test; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.core.annotation.Order; @Aspect @Order(1) public class UpdatePrintAspect { @Around("execution(* *(..)) && @annotation(UpdatePrint)") public Object logPrint(ProceedingJoinPoint pjp) throws Throwable{ String str = (String) pjp.getArgs()[0]; System.out.println("<<<< Starting doSomethingwithStr with str=" + str); Object retVal = pjp.proceed(); System.out.println("<<<< Done doSomethingwithStr with str=" + str); return retVal; } }
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:lang="http://www.springframework.org/schema/lang" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <!-- this switches on the load-time weaving --> <context:load-time-weaver aspectj-weaving="on"/> <bean id="myBean" class="com.test.MyBean"/> </beans>
This is the META-INF/aop.xml file:
This is the main class:Code:<aspectj> <aspects> <aspect name="com.test.UpdatePrintAspect"/> <aspect name="com.test.ReplaceStringAspect"/> </aspects> <weaver options="-verbose"> <include within="com.test.MyBean"/> </weaver> </aspectj>
This is the output. You can see that the the first advise changes the arguments successfully, but the second advice does not see the changed argument:Code:package com.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public final class Main { public static void main(String[] args) { ApplicationContext ctx = new FileSystemXmlApplicationContext("src/beans.xml"); MyBean bean = (MyBean) ctx.getBean("myBean"); bean.update("ONE."); } }
Code:Dec 28, 2009 5:05:21 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@1608e05: display name [org.springframework.context.support.FileSystemXmlApplicationContext@1608e05]; startup date [Mon Dec 28 17:05:21 EST 2009]; root of context hierarchy Dec 28, 2009 5:05:21 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from file [C:\eclipse_workspace\SpringAspectJ2\src\beans.xml] Dec 28, 2009 5:05:21 PM org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory INFO: Bean factory for application context [org.springframework.context.support.FileSystemXmlApplicationContext@1608e05]: org.springframework.beans.factory.support.DefaultListableBeanFactory@65a77f Dec 28, 2009 5:05:21 PM org.springframework.context.weaving.DefaultContextLoadTimeWeaver setBeanClassLoader INFO: Found Spring's JVM agent for instrumentation [AppClassLoader@130c19b] info AspectJ Weaver Version 1.6.6 built on Wednesday Sep 30, 2009 at 18:55:14 GMT [AppClassLoader@130c19b] info register classloader sun.misc.Launcher$AppClassLoader@130c19b [AppClassLoader@130c19b] info using configuration /C:/eclipse_workspace/SpringAspectJ2/lib/META-INF/aop.xml [AppClassLoader@130c19b] info register aspect com.test.UpdatePrintAspect [AppClassLoader@130c19b] info register aspect com.test.ReplaceStringAspect Dec 28, 2009 5:05:22 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@65a77f: defining beans [org.springframework.context.weaving.AspectJWeavingEnabler#0,loadTimeWeaver,myBean]; root of factory hierarchy ## Start ReplaceStringAspect. str=ONE.TWO. <<<< Starting doSomethingwithStr with str=ONE. doSomethingwithStr: ONE.TWO. <<<< Done doSomethingwithStr with str=ONE. ## Done ReplaceStringAspect. str=ONE.TWO.


Reply With Quote