简体   繁体   English

带有数组元素的Java自定义注释

[英]Java Custom annotation with array element

I have a custom annotation as follows. 我有一个自定义注释如下。

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnApiVersionConditional.class)
public @interface ConditionalOnApiVersion {

    int[] value() default 5;

    String property();
}

OnApiVersionConditional is, 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注释中,

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

There are beans with single version matching also, like 还有像单一版本匹配的bean

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

I would like to validate the userInput version from the property file to the available Beans supported versions. 我想验证属性文件中的userInput版本到可用的Beans支持版本。 Not sure, how can i get the value, iterate and compare with userInoutVersion. 不确定,如何获取值,迭代并与userInoutVersion进行比较。 The value could be 8 or {6,7} as an int array. 该值可以是8或{6,7}作为int数组。 Not sure, how can i iterate the value to check if any of the value is matching with the input version. 不确定,如何迭代该值以检查是否有任何值与输入版本匹配。

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

Question: 题:

How to iterate attributes.get("value") and compare with userInputVersion? 如何迭代attributes.get(“value”)并与userInputVersion进行比较?

attributes.get("value") returns a List of Object. attributes.get(“value”)返回一个Object列表。

I tried the below code, 我试过下面的代码,

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

boolean result = apiVersions.stream().anyMatch(version -> (int)version == Integer.parseInt(userInputVersion));

But getting the below error int eh 2nd line anyMatch, 但得到以下错误在第二行anyMatch,

java.lang.ClassCastException: [I cannot be cast to java.lang.Integer java.lang.ClassCastException:[我无法转换为java.lang.Integer

Thanks 谢谢

You have defined a good custom annotation which uses Spring's @Conditional and this process will only create beans if the property named ' property ' is present in the array value . 您已经定义了一个使用Spring的@Conditional的良好自定义注释,如果数组值中存在名为“ property ”的属性,则此过程将仅创建bean。

The annotation defines these two variables as follows: 注释定义了这两个变量如下:

  1. value : int[] (One or more supported versions) valueint [] (一个或多个受支持的版本)
  2. property : String (The name of the property to compare to) propertyString (要比较的属性的名称)

When you use the metadata to retrieve these values, Spring returns them as Objects. 当您使用元数据检索这些值时,Spring会将它们作为对象返回。 Casting these objects into the types you defined them as is a key step. 将这些对象转换为您定义它们的类型是关键步骤。 There is no need for streams as iterating an int[] array is trivial. 不需要流,因为迭代int []数组是微不足道的。

I tested various forms of your annotation (value = 5, value = {6,7}, etc) and found the following code to work well (@Conditional beans were only created if the version was correct). 我测试了各种形式的注释(值= 5,值= {6,7}等)并发现以下代码运行良好(仅在版本正确时才创建@Conditional beans)。

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 (i.e. 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 could be improved by validating both property and value; 通过验证属性和值可以改进这种方法; returning false if either of these contains bad/empty values, etc. 如果其中任何一个包含错误/空值等,则返回false。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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