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.