Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: Simple concept question: intercept multi-thread method?

  1. #1
    Join Date
    Aug 2006
    Posts
    16

    Default Simple concept question: intercept multi-thread method?

    Can I intercept method under multi-thread computing?

    Example:
    I have an public method analyze(). It is OK to intercept this method and I see the log.

    Then I add another public method asyncAnalyze() --

    public void asyncAnalyze() {
    Thread t = new Thread(new Runnable() {
    public void run() {
    analyze();
    }
    });

    t.start();
    }

    Funny thing is: when I call asyncAnalyze(), which calls analyze() indirectly, it runs fine but I didn't see any log. It's like analyze() is not intercepted if a call is from inner-class/multi-thread?

    My question is: How can I intercept analyze() in multi-thread?

    Thanks for the help!

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

    Default Doesn't look like multi-threading issue

    How are you intercepting? Using Spring AOP or AspectJ?

    It doesn't look like a multi-threading issue. Modify your program as follows and I think you will see the same behavior:
    Code:
    public void asyncAnalyze() {
        Runnable r = new Runnable() {
            public void run() {
                analyze();
           }
       };	
       r.run();
    }
    Ramnivas Laddad (Follow me on Twitter)
    AspectJ in Action: Enterprise AOP with Spring Applications (2nd edition). Now available!

  3. #3
    Join Date
    Aug 2006
    Posts
    16

    Default

    Find the answer in another reply.

    For anyone in same situation: it is impossible because Spring AOP doesn't intercept a call from the same instance.

  4. #4
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    This is a known problem when using the decorator pattern (which Spring AOP uses); the class that is being decorated has no knowledge of the decorator. If you are using the ProxyFactoryBean you can call setExposeProxy to true and then access it via http://www.springframework.org/docs/...opContext.html

    If you are using LTW or compile time weaving then ignore this post
    Colin Yates
    SpringSource - http://www.springsource.com - Spring Training, Consulting, and Support - "From the Source"
    Please read http://www.springframework.org/documentation
    Co-Author of Expert Spring MVC + Web Flow.

  5. #5

    Default Can you post a link?

    @marmot101

    You find the answer in an other reply.
    Can you post a link to that reply please?

    Jörg

  6. #6
    Join Date
    Aug 2006
    Posts
    16

    Default

    bellmann29,

    Sorry that I cannot find that topic. But the basic idea is: Spring AOP doesn't support interception from a function in the same class. It is definitely under this AOP category.

  7. #7
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Quote Originally Posted by marmot101
    But the basic idea is: Spring AOP doesn't support interception from a function in the same class. It is definitely under this AOP category.
    As I mentioned in my reply a couple of replies ago, Spring AOP *does* support interception from a function in the same class, you just need to do a bit more to get it to work.

    The fundamental problem is that Spring uses a decorator, in the form of a runtime generated proxy to execute the interceptors (transactional, logging etc.), this effectively means that there are two classes, the generated proxy and your "target" class. The target class has no knowledge of the proxied class, and thus when it calls methods on itself it is completely bypassing the proxy. You can make the target class aware of the proxy by using the AopContext class (http://www.springframework.org/docs/...opContext.html).

    To put it simply, Spring does the following:

    Code:
    public class MyClass {
      public void myFirstMethod() {
        mySecondMethod();
      }
    
      public void mySecondMethod() {
      }
    }
    
    public class ProxyGeneratedBySpringWhichLooksLikeMyClass {
      private final MyClass delegate;
      private final List interceptors;
      public ProxyGeneratedBySpringWhichLooksLikeMyClass (
                         MyClass myClass,
                          List interceptors
                         ) {
        this.delegate = myClass;
        this.interceptors = interceptors;
      }
    
      public void myFirstMethod() {
        runInterceptors();
        delegate.myFirstMethod();
      }
    
      public void mySecondMethod() {
        runInterceptors();
        delegate.mySecondMethod()
      }
    }
    The spring container will then do something like:

    Code:
      MyClass myClass = new ProxyGeneratedBySpringWhichLooksLikeMyClass(
                       new MyClass(),
                       interceptors);

    So when clients call myClass.myFirstMethod() they are actually talking to the runtime generated proxy, however, if myFirstMethod() calls mySecondMethod() the call to mySecondMethod will *not* go through the proxy.

    PLEASE(!!!) do not take the above code too seriously as Spring offers far more functionality, but hopefully it demonstrates the point.

    Also note that this is completely irrelevant if you are using compile time weaving which doesn't use a decorator/proxy but modifies the byte code directly.
    Colin Yates
    SpringSource - http://www.springsource.com - Spring Training, Consulting, and Support - "From the Source"
    Please read http://www.springframework.org/documentation
    Co-Author of Expert Spring MVC + Web Flow.

  8. #8
    Join Date
    Aug 2006
    Posts
    16

    Default

    Thanks Colin to clear things up. But I think the power of Spring is its unintrusiveness. If I make class aware of AOPContext, I'd rather make function call directly, i.e. call log4j to log the message instead of letting AOP do it.

    My intention is: write program as independent as possible. When I introduce AOPContext into business logic layer, it will prevent me to easily port to other situations.

    However, thanks for explaining the details, that make things clear -- especially from a Spring team member, I really appreciated.

    Best Regards.

  9. #9
    Join Date
    Aug 2006
    Location
    Now Germany, previously Ukraine
    Posts
    1,546

    Wink

    Quote Originally Posted by marmot101
    ...
    My intention is: write program as independent as possible. When I introduce AOPContext into business logic layer, it will prevent me to easily port to other situations.
    ...
    In this case you are bound to use "true" AOP product, e.g. AspectJ.

  10. #10
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Quote Originally Posted by marmot101
    My intention is: write program as independent as possible. When I introduce AOPContext into business logic layer, it will prevent me to easily port to other situations.
    This is a very good point.

    There are a number of more elegant solutions that I can think of, but I haven't really got time ATM to go into detail.

    Essentially, instead of calling this.doSomething() call getThis().doSomething() and then provide a setThis(MyBean). You could then write a BeanPostProcessor to find all beans that implement a setThis and inject the bean back into itself.

    Code:
      public class DefaultMyService implements MyService {
        private MyService decoratedThis;
    
        public void doFirstMethod() {
          ////
          getThis().doSecondMethod();
        }
    
        public void doSecondMethod() {
        }
    
        private MyService getThis() {
          return this.decoratedThis;
        }
        private void setThis(MyService myService) { 
          this.decoratedThis = myService;
        }
    
      }
    This means it isn't dependent on AOP, can be easily unit tested etc. I will leave the BeanPostProcessor up to you

    I will blog about this when I have more time.
    Colin Yates
    SpringSource - http://www.springsource.com - Spring Training, Consulting, and Support - "From the Source"
    Please read http://www.springframework.org/documentation
    Co-Author of Expert Spring MVC + Web Flow.

Posting Permissions

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