简体   繁体   中英

How to get annotation metadata of spring beans

In my spring project I have multiple implementations of an interface.

interface Car {

}

@Component
@ColorOptions({Color.RED})
class SportsCar implements Car {

}

class Truck implements Car {

}

@Configuration
class CarConfiguration {

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    @ColorOptions({Color.GREEN, Color.BLUE})
    public Truck oldTruck() {
        return new Truck();
    }

    @Bean
    @ColorOptions({Color.BLUE})
    public Truck newTruck() {
        return new Truck();
    }
}

What I would like to achieve is to create a spring bean which would be a Map containing all the implementations of the interface which would be grouped based on the metadata provided in the ColorOptions annotation.

    @Bean
    public Map<Color, List<Car>> groupedCars(List<Car> cars) {
        // ???
        return null;
    }

The org.springframework.beans.factory.ListableBeanFactory#findAnnotationOnBean provides an option to do it but I was able only to receive the values only in case I annotated a class. In case of spring beans which were defined in methods I do not get anything. Also I would like to avoid injecting the whole ApplicationContext and inject just the implementations of the interface. How can I implement that?

You can use java refection to iterate through the methods

public class RunCarConfiguration {
public static void main(String[] args) throws Exception {

    System.out.println("Testing grouped car ...");
    Class<CarConfiguration> obj = CarConfiguration.class;

    // Process @ColorOption
    if (obj.isAnnotationPresent(ColorOptions.class)) {
        Annotation annotation = obj.getAnnotation(ColorOptions.class);
        ColorOptions colorOptions = (ColorOptions) annotation;

        System.out.printf("%nColor :%s", colorOptions.color());
        System.out.printf("%nLastModified :%s%n%n",
                colorOptions.lastModified());

    }


Map <ColorOptions.Color, Car> groupedCar = new HashMap<ColorOptions.Color, Car>();
    // Process @Test
    for (Method method : obj.getDeclaredMethods()) {

        // if method is annotated with @Test
        if (method.isAnnotationPresent(ColorOptions.class)) {
            Annotation annotation = obj.getAnnotation(ColorOptions.class);
            ColorOptions colorOptions = (ColorOptions) annotation;

            try {
                method.invoke(obj.newInstance());
                if (method.isAnnotationPresent(ColorOptions.class)) {
                    System.out.printf("Test '%s' - has method annnotation %s %n" ,
                            method.getReturnType().getName(), 
                            method.getAnnotation(ColorOptions.class).color());
                    groupedCar.put( method.getAnnotation(ColorOptions.class).color(),
                            (Car)method.invoke(obj.newInstance()));
                }

            } catch (Throwable ex) {
                System.out.printf("Test '%s' - failed: %s %n" ,
                        method.getName(), ex.getCause());
            }
        }
    }

}
}

Have you tried ComponentScan

@Configuration
@ComponentScan(includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,
    classes = ColorOption.class))
public class ComponentScanAnnotationFilterApp { }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM