derM
derM

Reputation: 13691

Get values from 'composed Annotations' in Spring

With Spring, you can have some kind of composed annotations. A prominent example is the @SpringBootApplication-annotation, which is a composite of an @Configuration, @EnableAutoConfiguration and @ComponentScan.

I am trying to get all Beans that are affected by a certain annotation, i.e. ComponentScan.

Following this answer, I am using the following code:

for (T o : applicationContext.getBeansWithAnnotation(ComponentScan.class).values()) {
    ComponentScan ann = (ComponentScan) o.getClass().getAnnotation(ComponentScan.class);
    ...
}

which does not work, since not all beans, returned by getBeansWithAnnotation(ComponentScan.class) are indeed annotated with that annotation, since those that are e.g. annotated with @SpringBootApplication are (usually) not.

Now I am looking for some kind of generic way, to retrieve the value of an annotation, even when it is only added as piece of another annotation. How can I do this?

Upvotes: 1

Views: 1093

Answers (2)

derM
derM

Reputation: 13691

It turns out, there is a utility set AnnotatedElementUtils which allows you to handle those merged annotations.

for (Object annotated : context.getBeansWithAnnotation(ComponentScan.class).values()) {
    Class clazz = ClassUtils.getUserClass(annotated) // thank you jin!
    ComponentScan mergedAnnotation = AnnotatedElementUtils.getMergedAnnotation(clazz, ComponentScan.class);
    if (mergedAnnotation != null) { // For some reasons, this might still be null.
        // TODO: useful stuff.
    }
}

Upvotes: 2

jin
jin

Reputation: 440

it may be CglibProxy. so you can not directly get the Annotation.

ClassUtils.isCglibProxyClass(o)

for more see this


edit,you can add your logic code. find the ComponentScan.

if (ClassUtils.isCglibProxyClass(o.getClass())) {
            Annotation[] annotations = ClassUtils.getUserClass(o).getAnnotations();
            for (Annotation annotation : annotations) {
                ComponentScan annotation1 = annotation.annotationType().getAnnotation(ComponentScan.class);
// in my test code , ComponentScan can get here.for @SpringBootApplication 
                System.out.println(annotation1);
            }

        }

Upvotes: 1

Related Questions