Announcement Announcement Module
Collapse
No announcement yet.
AOP, Proxies, and method calling in same instance Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • AOP, Proxies, and method calling in same instance

    Spring can use JDK's Proxy mechanism to apply AOP. However, is it not true that an object instance that has an aspect applied by JDK's Proxy mechanism bypasses the aspect when it invokes its own methods? In other words, when an outside class invokes my proxied class, it will have the benefit of the aspect. But, if the proxied instance invokes another method on itself, then the aspect will not be applied on the method call. I should probably test this before posting, but I strongly suspect it is true. If true, this should be well documented as it can lead to difficult bugs.

  • #2
    Spring does not use bytecode instrumentation to implement AOP. So it is predictable that if a method of a proxied object calls an other method in the same object, the aspect will not be applied on the method call.
    Spring allows however to apply the aspect on this method call by setting exposeProxy to True and using AopContext.currentProxy().
    Code:
      //inside method1
      ((MyBean) AopContext.currentProxy()).method2();
    I find this approch a little intrusive.

    Comment


    • #3
      Originally posted by irbouho
      Spring does not use bytecode instrumentation to implement AOP. So it is predictable that if a method of a proxied object calls an other method in the same object, the aspect will not be applied on the method call.
      Spring allows however to apply the aspect on this method call by setting exposeProxy to True and using AopContext.currentProxy().
      Code:
        //inside method1
        ((MyBean) AopContext.currentProxy()).method2();
      I find this approch a little intrusive.
      Hello,

      Yeah, "a little" is quite an Euphemism, isn't it ? :-)

      I think this problem could be "partially" solved with the use of CLIB instead of Dynamic Proxies : since the target class will be subclassed, calls to this() will first cause the overriden method to execute, thus allowing the AOP mechanism to work.

      Of course there will still be some problems here with CGLib, since all the methods marked as "final" cannot be subclassed

      Do I have the point ? Or did I miss something ?

      Comment


      • #4
        An alternative solution could be the following:

        Introduce a "this" property (with getter and setter) and invoke methods on the same instance via the getter. So getThis().foo() instead of this.foo().

        The backing property is by default "this" but might be overriden with the proxy (if the instance is being proxied). If the proxy instance is being injected, no call to AOP specific methods is required.

        This approach is still a bit intrusive but works with and without a proxy being present.

        Regards,
        Andreas

        Comment


        • #5
          I think this problem could be "partially" solved with the use of CLIB instead of Dynamic Proxies : since the target class will be subclassed, calls to this() will first cause the overriden method to execute, thus allowing the AOP mechanism to work.
          Unfortunately this is not possible. CGLIB proxies must delegate to the target object as it's not possible to add behaviour to an existing object. e.g.

          Code:
          class AdvisedFoo extends Foo {
              Foo target;
          
              void fooBar() {
                  // do before advice
                  // do around advice
                  target.fooBar();
                  // do after advice        
              }
          }
          As you can see CGLIB is really no help at all and Andreas solution is looking pretty nice.

          Ollie

          Comment


          • #6
            Could you use a combination of BeanNameAware and BeanFactoryAware interfaces to retrieve a reference to itself?

            Comment


            • #7
              Originally posted by wpoitras
              Could you use a combination of BeanNameAware and BeanFactoryAware interfaces to retrieve a reference to itself?
              I think so. But then you are bound to Spring (and I think that's to be avoided).

              Regards,
              Andreas

              Comment


              • #8
                Originally posted by oliverhutchison
                I think this problem could be "partially" solved with the use of CLIB instead of Dynamic Proxies : since the target class will be subclassed, calls to this() will first cause the overriden method to execute, thus allowing the AOP mechanism to work.
                Unfortunately this is not possible. CGLIB proxies must delegate to the target object as it's not possible to add behaviour to an existing object. e.g.

                ...

                As you can see CGLIB is really no help at all and Andreas solution is looking pretty nice.

                Ollie
                Since I still haven't done this myself, I now doubt that you're right.
                Please refer to this thread : http://forum.springframework.org/sho...vokes Question where it is said that, apparently, this is possible.

                So I think someone doesn't correctly interpret the way CGLib works.
                Mmmm ... think I will try it myself to be sure ;-p[/url]
                Last edited by robyn; May 14th, 2006, 11:52 AM.

                Comment


                • #9
                  So I think someone doesn't correctly interpret the way CGLib works
                  Laurent,

                  it's quite simple. Using the standard Java APIs you can not dynamically add behaviour to an existing object instance or, for that matter, any loaded class.

                  If you take the time to *think* this through and you will see that I must be correct.

                  Ollie

                  Comment


                  • #10
                    Re: AOP, Proxies, and method calling in same instance

                    Originally posted by adepue
                    Spring can use JDK's Proxy mechanism to apply AOP. However, is it not true that an object instance that has an aspect applied by JDK's Proxy mechanism bypasses the aspect when it invokes its own methods? In other words, when an outside class invokes my proxied class, it will have the benefit of the aspect. But, if the proxied instance invokes another method on itself, then the aspect will not be applied on the method call. I should probably test this before posting, but I strongly suspect it is true. If true, this should be well documented as it can lead to difficult bugs.
                    So it is true, and should be documented. Today I've found a bug in my code that was caused by this behaviour.

                    Comment


                    • #11
                      proposed solution

                      please refer to the proposed solution for more info

                      http://forum.springframework.org/showthread.php?t=16896

                      Thanks,
                      Amit Chhajed
                      Last edited by robyn; May 15th, 2006, 07:03 PM.

                      Comment


                      • #12
                        this link doesn't work!!

                        Comment

                        Working...
                        X