获取指定类的所有成员属性上的指定注解的属性值

示例

javax.persistence.Column.java

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    String name() default "";

    boolean unique() default false;

    boolean nullable() default true;

    boolean insertable() default true;

    boolean updatable() default true;

    String columnDefinition() default "";

    String table() default "";

    int length() default 255;

    int precision() default 0;

    int scale() default 0;
}

com.pxl.springbootdemo.entity.Address .java

@Entity
@Data
public class Address {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;//id

    @Column(name = "phone", nullable = true, length = 11)
    private String phone;//手机

    @Column(name = "zipcode", nullable = true, length = 6)
    private String zipcode;//邮政编码

    @Column(name = "address", nullable = true, length = 100)
    private String addressStr;//地址

    @Column
    private String addressStr1;//地址

    private String addressStr2;//地址
    
    public static final Map<String, Boolean> COLUMN_ANNOTATION_VALUE_MAP = new HashMap<>();

    static {
        // 获取类中所有声明的字段
        Field[] fields = Address.class.getDeclaredFields();
        for (Field field : fields) {
            // 获取字段上的@Column注解
            Column columnAnnotation = field.getAnnotation(Column.class);
            if (columnAnnotation == null) {
                continue;
            }

            // 获取注解的name和nullable属性
            String name = columnAnnotation.name();
            boolean nullable = columnAnnotation.nullable();
            if (StrUtil.isEmpty(name)) {
                continue;
            }

            // 将name和nullable添加到Map中
            COLUMN_ANNOTATION_VALUE_MAP.put(name, nullable);
    }
}

优化-抽取工具方法

package com.pxl.springbootdemo.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.util.ReflectUtil;
import com.sun.tools.javac.util.Pair;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 注解工具类
 *
 * @date 2024/8/31
 */
public class AnnotationUtil extends cn.hutool.core.annotation.AnnotationUtil {

    /**
     * 获取指定类的包含指定注解的所有成员属性列表。
     *
     * @param beanClass       指定类
     * @param annotationClass 指定注解
     * @return 包含指定注解的所有成员属性列表
     */
    public static <A extends Annotation> List<Field> findAnnotatedFields(Class<?> beanClass, Class<A> annotationClass) {
        Field[] annotatedFields = ReflectUtil.getFields(beanClass, field -> getAnnotation(field, annotationClass) != null);
        if (annotatedFields == null) {
            return Collections.emptyList();
        }
        return Arrays.asList(annotatedFields);
    }

    /**
     * 获取指定类的所有成员属性包含的指定注解列表。
     *
     * @param beanClass       指定类
     * @param annotationClass 指定注解
     * @param <A>             注解类型
     * @return 所有成员属性包含的指定注解列表
     */
    public static <A extends Annotation> List<A> findAnnotationsOnFields(Class<?> beanClass, Class<A> annotationClass) {
        Field[] fields = ReflectUtil.getFields(beanClass);
        if (fields == null) {
            return Collections.emptyList();
        }
        return Arrays.stream(fields)
                .map(field -> AnnotationUtils.getAnnotation(field, annotationClass))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    /**
     * 获取指定类的所有成员属性包含的指定注解的指定属性列表。
     *
     * @param beanClass       指定类
     * @param annotationClass 指定注解
     * @param propertyName    获取属性值的函数
     * @param predicate       属性值过滤函数
     * @param <A>             注解类型
     * @param <R>             属性值类型
     * @return 所有成员属性包含的指定注解的指定属性列表
     */
    public static <A extends Annotation, R> List<R> getAnnotationValuesOnFields(Class<?> beanClass, Class<A> annotationClass
            , Func1<A, R> propertyName, Predicate<R> predicate) {
        List<A> annotations = findAnnotationsOnFields(beanClass, annotationClass);
        return CollUtil.emptyIfNull(annotations)
                .stream()
                .map(propertyName::callWithRuntimeException)
                .filter(predicate)
                .collect(Collectors.toList());
    }

    /**
     * 获取指定类的所有成员属性上指定注解的指定两个属性值,并返回一个Map,key为第一个属性值,value为第二个属性值
     *
     * @param beanClass         指定类
     * @param annotationClass   指定注解
     * @param keyPropertyName   获取第一个属性值的函数
     * @param valuePropertyName 获取第二个属性值的函数
     * @param predicate         第一个属性值和第二个属性值的过滤函数
     * @param <A>               注解类型
     * @param <R1>              第一个属性值类型
     * @param <R2>              第二个属性值类型
     * @return 指定类的所有成员属性上指定注解的指定两个属性值
     */
    public static <A extends Annotation, R1, R2> Map<R1, R2> getTwoAnnotationValues(Class<?> beanClass, Class<A> annotationClass
            , Func1<A, R1> keyPropertyName, Func1<A, R2> valuePropertyName, BiPredicate<R1, R2> predicate) {
        List<A> annotations = findAnnotationsOnFields(beanClass, annotationClass);
        return CollUtil.emptyIfNull(annotations)
                .stream()
                .map(e -> Pair.of(keyPropertyName.callWithRuntimeException(e), valuePropertyName.callWithRuntimeException(e)))
                .filter(pair -> predicate.test(pair.fst, pair.snd))
                .collect(Collectors.toMap(pair -> pair.fst, pair -> pair.snd, (k1, k2) -> k1));
    }
}
public class Address {
    public static final Map<String, Boolean> COLUMN_ANNOTATION_VALUE_MAP = AnnotationUtil.getTwoAnnotationValues(Address.class, Column.class, Column::name, Column::nullable
            , ObjUtil::isAllNotEmpty);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java注解中也可以将参数设置为注解对象的某个属性。具体实现方法是在注解定义时声明成员变量型为注解型,然后在使用注解时,通过指定成员变量名和注解对象属性名来传递注解对象属性。例如: ``` @MyAnnotation(value = "example", objectValue = @MyObjectAnnotation(name = "objName", value = "objValue")) public class MyClass { // class body } @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { String value(); MyObjectAnnotation objectValue(); String name() default ""; } @Retention(RetentionPolicy.RUNTIME) public @interface MyObjectAnnotation { String name(); String value(); } ``` 在上面的例子中,`@MyAnnotation` 是一个自定义注解,其中定义了两个成员变量:`value` 和 `objectValue`,分别为字符串型和自定义注解型。在 MyClass 中使用注解时,通过 `value = "example"` 和 `objectValue = @MyObjectAnnotation(name = "objName", value = "objValue")` 来传递对象属性。其中 `@MyObjectAnnotation` 也是一个自定义注解,用来传递对象属性。在 `@MyAnnotation` 中定义了一个 `name` 属性,用来指定注解对象的属性名,如下所示: ``` @MyAnnotation(value = "example", objectValue = @MyObjectAnnotation(name = "objName", value = "objValue"), name = "value") public class MyClass { // class body } ``` 在上面的例子中,通过 `name = "value"` 来指定 `@MyAnnotation` 中的 `value` 属性注解对象的属性名。这样,在使用注解时,就可以通过 `@MyAnnotation` 的 `name` 属性指定注解对象的属性名,如下所示: ``` MyAnnotation myAnnotation = MyClass.class.getAnnotation(MyAnnotation.class); String objectValue = myAnnotation.objectValue().value(); String value = myAnnotation.name().isEmpty() ? myAnnotation.value() : (String) myAnnotation.objectValue().getClass().getMethod(myAnnotation.name()).invoke(myAnnotation.objectValue()); ``` 在上面的例子中,通过 `MyClass.class.getAnnotation(MyAnnotation.class)` 来获取 `@MyAnnotation` 注解对象,然后通过 `myAnnotation.objectValue().value()` 和 `myAnnotation.name()` 来获取注解对象的属性。其中,通过判断 `myAnnotation.name().isEmpty()` 是否为空来判断是否需要获取注解对象的属性。如果 `name` 属性为空,则直接获取 `value` 属性,否则通过反射获取注解对象的属性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值