Java Custom annotation with array element

I have a custom annotation as shown below.

@Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD }) @Documented @Conditional(OnApiVersionConditional.class) public @interface ConditionalOnApiVersion { int[] value() default 5; String property(); } 

OnApiVersionConditional,

 public class OnApiVersionConditional implements Condition { @Override public boolean matches(final ConditionContext context, final AnnotatedTypeMetadata metadata) { final MultiValueMap<String, Object> attributes = metadata.getAllAnnotationAttributes(ConditionalOnApiVersion.class.getName()); attributes.get("value"); final String inputVersion = context.getEnvironment().getProperty("userInputVersion"); } 

In my Bean annotation

  @Bean @ConditionalOnApiVersion(value = {6, 7}, property = "userInputVersion") 

There are beans with the same version match, for example

 @Bean @ConditionalOnApiVersion(value = 8, property = "userInputVersion") 

I would like to check the version of userInput from the properties file for available versions of beans. Not sure how I can get the value, repeat and compare with userInoutVersion. The value can be 8 or {6,7} as an int array. Not sure how I can repeat the value to check if any value matches the input version.

final List apiVersions = attributes.get ("value"). stream (). collect (Collectors.toList ());

Question:

How to iterate attribute.get ("value") and compare with userInputVersion?

attributes.get ("value") returns a list of objects.

I tried the code below,

 final List<Object> apiVersions = attributes.get("value").stream().collect(Collectors.toList()); boolean result = apiVersions.stream().anyMatch(version -> (int)version == Integer.parseInt(userInputVersion)); 

But getting below error int eh 2nd line anyMatch,

java.lang.ClassCastException: [I cannot be added to java.lang.Integer

thanks

+5
source share
1 answer

You have defined a good custom annotation that Spring @Conditional uses, and this process will only create beans if a property called "property" is present in the value of the array.

Annotations define these two variables as follows:

  • value: int [] (one or more supported versions)
  • property: String (name of the property to be compared)

When you use metadata to retrieve these values, Spring returns them as objects. Passing these objects to the types that you define for them is a key step. There is no need for threads, since the iteration of the int [] array is trivial.

I tested various forms of annotation (value = 5, value = {6,7}, etc.) and found that the following code works well (@Conditional beans were only created if the version was correct).

 public class OnApiVersionConditional implements Condition { @Override public boolean matches(final ConditionContext context, final AnnotatedTypeMetadata metadata) { final MultiValueMap<String, Object> attributes = metadata .getAllAnnotationAttributes(ConditionalOnApiVersion.class.getName()); // 1. Retrieve the property name from the annotation (ie userInputVersion) List<Object> propertyObject = attributes.get("property"); // 2. Cast it to a String String propertyName = (String)propertyObject.get(0); // 3. Retrieve the value List<Object> list = attributes.get("value"); // 4. Cast it to int[] int[] values = (int[])list.get(0); // 5. Look up the actual version (based on the property name in the annotation) final String inputVersion = context.getEnvironment().getProperty(propertyName); // Assume it is an integer? int version = Integer.valueOf(inputVersion).intValue(); // 6. Scan the supported version; look to match against actual version for (int i : values) if (i == version) return true; // The version is not supported return false; } } 

This method can be improved by checking both the property and the value; returns false if any of them contains invalid / empty values, etc.

+3
source

Source: https://habr.com/ru/post/1275150/


All Articles