Results 1 to 7 of 7

Thread: AOP doesn't create proxy for superclass's method for web applications

  1. #1
    Join Date
    Sep 2012
    Posts
    3

    Default AOP doesn't create proxy for superclass's method for web applications

    Hi, guys

    I faced a problem with proxing classes hierarhy.

    Problem:
    Code:
    package com.main;
    
    public interface A {
       void find();
       
       void query();
    }
    Code:
    package com.main;
    
    public class B implements A {
       public void find() {
       }
       
       public void query() {
       }
    }
    Code:
    package com.main.test;
    
    import com.main.A;
    import com.main.B;
    import com.main.annotation.TimeTracked;
    
    @TimeTracked("cool")
    public class C extends B {
       public void find() {
       }
    }
    Code:
    package com.main.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    public @interface TimeTracked {
    
        String value();
    }
    Aspect:
    Code:
    package com.main.aop;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    
    @Aspect
    public class TimeTrackingAspect {
    
        @Pointcut("@within(com.jingit.commons.logging.statistic.time.TimeTracked)")
        private void annotatedClass() {
        }
    
        @Pointcut("execution(public * *.*(..))")
        private void publicMethod() {
        }
    
        @Around("annotatedClass() && publicMethod()")
        public Object trackAnnotatedClassCalls(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
               System.out.println("trackAnnotatedClassCalls");
               return proceedingJoinPoint.proceed();
        }
    }
    And I use class C like:
    Code:
    @Autowired
    private A c;
    There are all necessary Spring configs and so on.

    Problem is when I use "c" bean in unit tests aspect catches all methods "find" and "query" but when I use "c" bean in my spring mvc web application aspect catches only "find" method that is overrided in class C.

    What I have found is the different between these two cases it is application contexts.

    Could you help me to solve this problem? May be you have some advice, expirience with it and so on.

    Best regards,
    Andrey.

  2. #2
    Join Date
    Sep 2012
    Location
    Czech Republic
    Posts
    39

    Default

    Use @target instead of @within in your annotatedClass() pointcut.
    Spring reference says
    @within - limits matching to join points within types that have the given annotation (the execution of >>>methods declared in types with the given annotation<<< when using Spring AOP)

  3. #3
    Join Date
    Sep 2012
    Posts
    3

    Default

    @target creates proxy for all beans it is bad for me, @within also works as you mentioned.

    How to solve it?

  4. #4
    Join Date
    Sep 2012
    Location
    Czech Republic
    Posts
    39

    Default

    >> @target creates proxy for all beans
    What exactly do you mean by "all beans"? Proxies are created only for beans that matches a pointcut, @target(Annotation) matches only beans of classes annotated with Annotation. Another restriction you can do is to remove @Inherited in the Annotation, child classes are not matched in this case.

  5. #5
    Join Date
    May 2011
    Location
    New Delhi, India
    Posts
    157

    Default

    Is the "query" method in the web application being called from "find" method? If this is the case then Spring AOP will not be able to intercept calls to "query" method.

    Refer to slide # 15 @ (http://www.google.co.in/url?sa=t&rct...v1NQXLnxzq3yFA)

  6. #6
    Join Date
    May 2013
    Posts
    1

    Default

    Quote Originally Posted by bitsal View Post
    Hi, guys

    I faced a problem with proxing classes hierarhy.

    Problem:
    Code:
    package com.main;
    
    public interface A {
       void find();
       
       void query();
    }
    Code:
    package com.main;
    
    public class B implements A {
       public void find() {
       }
       
       public void query() {
       }
    }
    Code:
    package com.main.test;
    
    import com.main.A;
    import com.main.B;
    import com.main.annotation.TimeTracked;
    
    @TimeTracked("cool")
    public class C extends B {
       public void find() {
       }
    }
    Code:
    package com.main.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    public @interface TimeTracked {
    
        String value();
    }
    Aspect:
    Code:
    package com.main.aop;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    
    @Aspect
    public class TimeTrackingAspect {
    
        @Pointcut("@within(com.jingit.commons.logging.statistic.time.TimeTracked)")
        private void annotatedClass() {
        }
    
        @Pointcut("execution(public * *.*(..))")
        private void publicMethod() {
        }
    
        @Around("annotatedClass() && publicMethod()")
        public Object trackAnnotatedClassCalls(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
               System.out.println("trackAnnotatedClassCalls");
               return proceedingJoinPoint.proceed();
        }
    }
    And I use class C like:
    Code:
    @Autowired
    private A c;
    There are all necessary Spring configs and so on.

    Problem with my top website designers is when I use "c" bean in unit tests aspect catches all methods "find" and "query" but when I use "c" bean in my spring mvc web application aspect catches only "find" method that is overrided in class C.

    What I have found is the different between these two cases it is application contexts.

    Could you help me to solve this problem? May be you have some advice, expirience with it and so on.

    Best regards,
    Andrey.
    what do you mean by 'all beans?'

  7. #7
    Join Date
    Sep 2012
    Posts
    3

    Default

    Quote Originally Posted by skylatt View Post
    what do you mean by 'all beans?'
    I mean all beans in Spring container including not annotated.

    BTW, this problem is not of my current interest.
    Thank you.

Posting Permissions

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