Announcement Announcement Module
Collapse
No announcement yet.
AOP doesn't create proxy for superclass's method for web applications Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    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)

    Comment


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

      How to solve it?

      Comment


      • #4
        >> @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.

        Comment


        • #5
          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)

          Comment


          • #6
            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?'

            Comment


            • #7
              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.

              Comment

              Working...
              X