Announcement Announcement Module
Collapse
No announcement yet.
Inherit Annotation from Interface for pointcutting Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Inherit Annotation from Interface for pointcutting

    Hi!

    I would like to annotate my business interfaces so I can define pointcuts for them. Something like:

    Code:
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface BusinessInterface {
    }
    
    @BusinessInterface
    public interface MyBusinessInterface {
        public void myBusinessMethod();
    }
    
    public class MyBusinessImpl implements MyBusinessInterface {
        public void myBusinessMethod() {
            ...
        }
    }
    
    @Pointcut("@within(BusinessInterface)")
    protected void businessInterface() {
    }
    
    @Around("businessInterface()")
    protected Object myBusinessInterfaceCall(ProceedingJoinPoint joinPoint) throws Throwable {
        ...
    }
    Too bad that annotations on interfaces are not inheritable... only class annotations can!!!

    Is there any way I can still define a pointcut for all implementations of an interface?!?

    I think this is not such an esoteric requirement, is it?!?


    Kind regards!

  • #2
    execution(* com.xxx.xxx.BusinessInterface+.*(..)) should do it.

    Comment


    • #3
      Hi bdangubic,

      I don't understand what the "+" means, it's obviously not in the Spring doc.

      But while specifying the interface directly like in ...
      Code:
          @Pointcut("execution(* com.xxx.xxx.MyBusinessInterface.*(..))")
      ... works, simply changing it to ...
      Code:
          @Pointcut("execution(* com.xxx.xxx.BusinessInterface+.*(..))")
      ... doesn't work ;-(

      Any ideas, as to why?!?


      Kind Regards

      Comment


      • #4
        the extra + is for matching any classes that implement the interface MyBusinessInterface. not sure why it does not work for you though...

        Comment


        • #5
          If I understand you correctly, then this would work:

          Code:
          @Pointcut("execution(* com.xxx.xxx.MyBusinessInterface+.*(..))")
          But what I want is one more indirection: MyBusinessImpl implements MyBusinessInterface which in turn is annotated as BusinessInterface, and I want my pointcut to match all implementations of all interfaces annotated to be BusinessInterfaces.

          I could use a naming convention like this:

          Code:
          @Pointcut("execution(* com.xxx.xxx.*BusinessInterface+.*(..))")
          But that would make the names of my business interfaces quite long winded. And eventually I would have to fetch the values of the annotation by hand.

          Comment


          • #6
            Why don't you annotate your business classes instead of your business interfaces?

            This should work:

            @BusinessInterface
            public class MyBusinessImpl implements MyBusinessInterface {
            public void myBusinessMethod() {
            ...
            }
            }

            Comment


            • #7
              I had been thinking of that first, by I may want to have different implementations for the same interface.

              Comment


              • #8
                So? You'll have to annotate all your different implementations.

                Comment


                • #9
                  Try this

                  Code:
                  @Pointcut("this(BusinessInterfaceMarker)")
                  protected void businessInterface() {}
                  
                  public interface MyBusinessInterface extends BusinessInterfaceMarker {
                  	public void myBusinessMethod();
                  }
                  Now all method that belong to a BusinessMarkerInterface get adviced.

                  Comment


                  • #10
                    Right now I'm annotating all implementations, but it is not as elegant as I would have liked it to be. Making the BusinessInterface not an annotation but a base interface as you suggesed works as well, but then I don't have an annotation object with values that I can access.

                    Nevertheless: Thanks for all the ideas... I guess there is simply no super-elegant solution (yet?).

                    Kind regards

                    Comment


                    • #11
                      Your problem seams to be a Java problem instead of a Spring related problem. What you try to achieve is currently not possible because Java does not support annotation inheritance.

                      There is however a library that lets you use inherited annotations.

                      If you want to use this, I guess you will have to write your own implementation of AspectJ pointcut and advice so it uses this library.

                      Looks like a nice challenge...

                      Comment


                      • #12
                        In my first post I pointed out: "Too bad that annotations on interfaces are not inheritable... only class annotations can!!!"

                        I was hoping that there was some pointcut type that I was not aware of that would help me around this restriction. Obviously there is none.

                        Just to learn something: Do you have a link as to how to implement my own pointcut type in Spring? Or is Spring not built for this kind of extension, which I would understand very well, but Spring has suprised me many times ;-)

                        Comment

                        Working...
                        X