Announcement Announcement Module
Collapse
No announcement yet.
MethodInterceptor and Parameters Question Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • MethodInterceptor and Parameters Question

    Please excuse this question, as it may be total AOP newbie material.

    I am using the MethodInterceptor to intercept calls to ClassA.getByName(String name) and redirecting to ClassB.getByName(String name).

    My question is how do I get the parameters from the call to ClassA and pass them to ClassB?

  • #2
    You need to use "around" advice. You define the advice around the ClassA.getByName() and take a PreceedingJoinPoint.

    Something like the following (no guarantee to work or compile, just thinking aloud):

    Code:
    <aop:config>
        <aop:aspect id="classAInterceptor" ref="adviceBean">
            <aop:pointcut id="classAGetByNameMethod" expression="execution(* ClassA+.getByName(*))"/>
            <aop:advisor pointcut-ref="classAGetByNameMethod" method="interceptMethod"/>
         </aop:aspect>
    </aop:config>
    
    <bean id="adviceBean"  class="com.you.YourAdvice">
        <constructor arg>
            <bean class="com.you.ClassB"/>
        </constructor-arg>
    </bean>
    and the code:

    Code:
    public class YourAdvice {
        private ClassB classB;
    
        public YourAdvice(ClassB classB) {
            this.classB = classB;
        }
    
        public void interceptMethod(ProceedingJoinPoint p) {
            Object o = getArgs()[0];// the string argument
            String arg = (String)o;
            return this.classB.getByName(arg);        
        }
    }
    The horrible type cast can be avoided by using the pointcut to pick out the string argument etc.

    For more info, please read http://static.springframework.org/sp...rence/aop.html and if you are new to 2.5; http://static.springframework.org/sp...l#new-in-2-aop

    Comment


    • #3
      Unfortunately, I can't take advantage of the XML Schema based configuration, as I'm using an older version of an IDE that can't handle it (anyone want to fund 35 IDEA 7.0 licenses for me? )

      Another point... shouldn't your interceptMethod() return Object instead of void? (Sorry to quibble, I just need to make sure I understand what you are saying).

      Originally posted by Colin Yates View Post
      You need to use "around" advice. You define the advice around the ClassA.getByName() and take a PreceedingJoinPoint.

      Something like the following (no guarantee to work or compile, just thinking aloud):

      Code:
      <aop:config>
          <aop:aspect id="classAInterceptor" ref="adviceBean">
              <aop:pointcut id="classAGetByNameMethod" expression="execution(* ClassA+.getByName(*))"/>
              <aop:advisor pointcut-ref="classAGetByNameMethod" method="interceptMethod"/>
           </aop:aspect>
      </aop:config>
      
      <bean id="adviceBean"  class="com.you.YourAdvice">
          <constructor arg>
              <bean class="com.you.ClassB"/>
          </constructor-arg>
      </bean>
      and the code:

      Code:
      public class YourAdvice {
          private ClassB classB;
      
          public YourAdvice(ClassB classB) {
              this.classB = classB;
          }
      
          public void interceptMethod(ProceedingJoinPoint p) {
              Object o = getArgs()[0];// the string argument
              String arg = (String)o;
              return this.classB.getByName(arg);        
          }
      }
      The horrible type cast can be avoided by using the pointcut to pick out the string argument etc.

      For more info, please read http://static.springframework.org/sp...rence/aop.html and if you are new to 2.5; http://static.springframework.org/sp...l#new-in-2-aop

      Comment


      • #4
        Originally posted by DartmanX View Post
        Unfortunately, I can't take advantage of the XML Schema based configuration, as I'm using an older version of an IDE that can't handle it (anyone want to fund 35 IDEA 7.0 licenses for me? )

        Another point... shouldn't your interceptMethod() return Object instead of void? (Sorry to quibble, I just need to make sure I understand what you are saying).
        Nope, you are right, it should return an Object, assuming that getByName returns something....

        What problems are you having exactly?

        Comment


        • #5
          I can't precisely say that I was having a particular problem. However, I had not been able to find a reference for implementing a MethodInterceptor that redirected one method call to another using the same arguments.

          In the Javadocs for ReflectiveMethodInvocation, I saw the getArguments() which returns Object[]. However, I didn't know if I could create use getArguments(), then change the target class/method, then apply the same arguments. At this point all I would have to do would be invocation.proceed().

          Russell Miles has an excellent article about the Cuckoo's Egg pattern at http://www.onjava.com/pub/a/onjava/2...pringaop2.html. Unfortunately, when he intercepts a call to one method to call another one instead, he doesn't pass parameters. I find this pattern to be a very interesting way to deal with poor quality legacy code.

          Comment


          • #6
            Your MethodInterceptor should look the same as "YourAdvice", although obviously implementing the MethodInterceptor interface and implementing the invoke method.

            You don't want to change the MethodInvocation object at all, simply call the method on your ClassB the way you would normally. The arguments to the ClassB method are extracted from the MethodInvocation.getArguments().

            Comment


            • #7
              Okay, thanks for the hit with the clue-by-four. The answer is VERY obvious now that you point it out.

              Thanks for your help.

              Comment

              Working...
              X