Announcement Announcement Module
Collapse
No announcement yet.
Metod Advice + inner object method invokes Question Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Metod Advice + inner object method invokes Question

    Hi Alls,

    I have 3 methods in my class
    Code:
    public void startRuleSet() {
        System.out.println("Start Rule Set");
        makeRule1();
        makeRule2();
      }
    
      public void makeRule1() {
        System.out.println("Rule 1");
      }
    
      public void makeRule2() {
        System.out.println("Rule 2");
      }
    in spring config there're such lines:
    Code:
      <bean id="myBefore" class="com.my.test.aop.MyBefore"/>
    
      <bean id="ruleSetAOPTest" class="com.my.test.aop.RuleSetAOPImpl"/>
    
      <bean id="ruleAdvisor"
        class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="advice">
          <ref local="myBefore"/>
        </property>
        <property name="pattern">
          <value>.*Rule.*</value>
        </property>
      </bean>
    
      <bean id="ruleSetBean" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target">
          <ref local="ruleSetAOPTest"/>
        </property>
        <property name="proxyTargetClass">
          <value>true</value>
        </property>
        <property name="interceptorNames">
          <list>
            <value>ruleAdvisor</value>
          </list>
        </property>
      </bean>
    And when i call startRuleSet
    Code:
    final RuleSetAOPImpl ruleSet = &#40;RuleSetAOPImpl&#41; context.getContext&#40;&#41;.getBean&#40;"ruleSetBean"&#41;;
        ruleSet.startRuleSet&#40;&#41;;
    I have advice invoke only on startRuleSet(), but i want that advice is invoked on makeRule* methods which are invoked inside startRuleSet method.

    Is it possible ?

    Thank's

  • #2
    Please take a look at AOP, Proxies, and method calling in same instance and Pre-Interceptor in TransactionProxyFactory.
    HTH

    Comment


    • #3
      But in this case object has to know about AOP and that it is interceptored now.
      I don't like such solution because i need clean pojo not agly hybrid.

      Originally posted by irbouho

      Comment


      • #4
        As I said in a previous post, this approach is intrusive. You may, however use AspectJ for less intrusive approach.

        Comment


        • #5
          I cann't do it because my class instanses will load from db.
          And i think it's impossible to use AspectJ in such case only runtime byte code manipulation.
          Originally posted by irbouho
          As I said in a previous post, this approach is intrusive. You may, however use AspectJ for less intrusive approach.

          Comment


          • #6
            Originally posted by irbouho
            As I said in a previous post, this approach is intrusive. You may, however use AspectJ for less intrusive approach.
            Hello,

            What about this :

            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


            • #7
              You're right. I made this thing using cglib

              Originally posted by Laurent PETIT
              Originally posted by irbouho
              As I said in a previous post, this approach is intrusive. You may, however use AspectJ for less intrusive approach.
              Hello,

              What about this :

              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


              • #8
                Do I have the point ? Or did I miss something?
                You missed something.

                Using CGLIB proxies will not solve this problem as, just like JDK proxies, they delegate to the target. See: http://forum.springframework.org/showthread.php?t=9926

                Ollie
                Last edited by robyn; May 16th, 2006, 03:51 AM.

                Comment


                • #9
                  You're wrong
                  when i have 3 public methods:
                  Code:
                  public a() {
                    b();
                    c();
                  }
                  
                  public b() {...}
                  
                  public c() {...}
                  then using cglib proxy i can intercept for all 3 methods. And "a" method is invoked from outside but "b" and "c" from "a" and everything's working.

                  Originally posted by oliverhutchison
                  Do I have the point ? Or did I miss something?
                  You missed something.

                  Using CGLIB proxies will not solve this problem as, just like JDK proxies, they delegate to the target. See: http://forum.springframework.org/showthread.php?t=9926

                  Ollie
                  [/code]
                  Last edited by robyn; May 16th, 2006, 03:50 AM.

                  Comment


                  • #10
                    I would say the difference between Java proxies and CGLIB proxies is the following:

                    A Java proxy effectively establishes a delegate. You call a method on the proxy which eventually delegates to the target. Once inside the target's method the invocation of another method will take place in the context of the target, not of the proxy.

                    I assume a CGLIB proxy establishes a subclass of the target class. So you never leave the context. Operating on "this" effectively operates on the subclass (proxy) instance. So subsequent invocations take place on the proxied methods (if not private).

                    It's a difference between delegation and inheritance, therefore the former does not work while the latter does.

                    Regards,
                    Andreas

                    P.S.: I'm no expert for CGLIB. It's just an explanation of how I think it works

                    Comment


                    • #11
                      Guys this is getting silly.

                      CGLIB proxies DO delegate just like JDK proxies. It's true that CGLIB generates a subclass but that subclass must delegate to the target object.

                      Remember the target can change after the proxy has been created.

                      Think it through!

                      Ollie

                      Comment


                      • #12
                        Hopefully this puts this silly discussion to rest:

                        Code:
                        public class ProxyTest extends TestCase &#123;
                        
                            public static class SelfCaller &#123;
                                boolean calleeCalled = false;
                        
                                public void callSelf&#40;&#41; &#123;
                                    callee&#40;&#41;;
                                &#125;
                        
                                public void callee&#40;&#41; &#123;
                                    calleeCalled = true;
                                &#125;
                            &#125;
                        
                            public void testProxy&#40;&#41; &#123;
                                CountingBeforeAdvice counter = new CountingBeforeAdvice&#40;&#41;;
                                SelfCaller target = new SelfCaller&#40;&#41;;
                                ProxyFactory pf = new ProxyFactory&#40;target&#41;;
                                pf.setProxyTargetClass&#40;true&#41;;
                                pf.addAdvice&#40;counter&#41;;
                        
                                SelfCaller proxy = &#40;SelfCaller&#41;pf.getProxy&#40;&#41;;
                                
                                proxy.callee&#40;&#41;;
                                assertTrue&#40;target.calleeCalled&#41;;
                                assertEquals&#40;"Direct invocation of callee was not intercepted", 1,
                                        counter.getCalls&#40;&#41;&#41;;
                        
                                target.calleeCalled = false;
                                proxy.callSelf&#40;&#41;;
                         
                                assertTrue&#40;target.calleeCalled&#41;;
                                // if the self call was advised you would now expect counter.getCalls&#40;&#41; to
                                // equal 3
                                assertEquals&#40;"Invocation of callee must have been advised as more than one invocation was intercepted", 2,
                                        counter.getCalls&#40;&#41;&#41;;
                            &#125;
                        &#125;
                        In future guys - please check your facts before you post.

                        Ollie

                        Comment


                        • #13
                          Originally posted by oliverhutchison
                          Hopefully this puts this silly discussion to rest:

                          Code:
                          ...
                          In future guys - please check your facts before you post.

                          Ollie
                          Unfortunately, Oliver is right, I've checked it by myself.

                          I can't explain why darkit told us he could do this, but it was indeed a false hope to me.

                          --
                          Laurent

                          Comment

                          Working...
                          X