How can I refer to implementations of a method in annotation processing?

你说的曾经没有我的故事 提交于 2019-12-03 09:53:45

The short answer is that out-of-the-box annotation processing isn't going to make this easy for you, but it can be done.

Rather than using the normal dispatch mechanism for processing, you're actually going to have to process every method and do the filtering yourself.

Step 1:

Define your processor so that it supports all annotations by using "*" as its supported annotation type. This will mean that your processor will get invoked every round.

Step 2:

Use getRootElements to get the entire set of elements every round.

Step 3:

Create an ElementScanner8 to traverse any element that you find to look for ExecutableElements. If you're willing to trust that overridden methods are annotated with @Override, you can do a quick filter on those. Otherwise, just look at all of them.

Step 4:

Now you need to see if the method overrides a method with the annotation you're looking for. There's no easy way to get methods that a given method has overridden, so you need to get the enclosing element of the method, look at its superclass and implemented interfaces (recursively), get their enclosed elements, filter out the methods, and test to see if it has been overridden by the method in question. If it has, you can check the annotations to see if it has one you care about.

Step 5:

At this point, you should have the overriding method, the overridden method and the annotation mirror that you were looking for, so you should be able to implement whatever logic you wanted.

Koos Gadellaa

If those annotations are available at runtime, and you want to reach them at runtime, you can use the Reflections library.

For example:

Collection<URL> urls = ClasspathHelper.forPackage("nl.shopname.location.domain");

Reflections reflections = new Reflections(
    new ConfigurationBuilder().setUrls(urls).setScanners(new FieldAnnotationsScanner()));

Set<Field> fieldsWithAnnotation = reflections.getFieldsAnnotatedWith(MyAnnotation.class); 

according to the javadoc of javax.annotation.processing.Processor in Jsr269-1.8

An annotation is present if it meets the definition of being present given in AnnotatedConstruct. In brief, an annotation is considered present for the purposes of discovery if it is directly present or present via inheritance. An annotation is not considered present by virtue of being wrapped by a container annotation...

The JavaDoc of AnnotatedConstruct#getAnnotationsByType says that it returns indirectly present annotations, so I think you should scan for methods and check if they indirectly have the annotation using this call. Something in the spirit of this.

Disclaimer... haven't tried it ;)

Method annotations are not inherited. Type annotations can be inherited through the use of "@Inherited" annotation.

What you could do is define a functional interface with an inherited type annotation, however I don't know if this is elegant enough for you.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!