java 8 利用lambda 获取 记录类(get/set) field 上面 注解

发布时间 2023-11-30 16:47:59作者: _Y_h
package tianrun.ziguan.api.center.alert.util;

import com.baomidou.mybatisplus.annotation.TableField;

import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.function.Function;

/**
 * @author: Yh
 * @date: 2023/11/30 15:37
 */
public class ClassUtil {

    public static String column(FF<?, ?> func) {
        TableField o = resolveLambdaProxyFieldAnnotation(func, TableField.class);
        if (o == null) {
            return "";
        }
        return o.value();
    }

    public static <T> T resolveLambdaProxyFieldAnnotation(FF<?, ?> func, Class<T> an) {
        SerializedLambda resolve = resolve(func);
        final String implMethodName = resolve.getImplMethodName().toUpperCase();
        try {
            Class<?> implClass = Class.forName(resolve.getImplClass().replaceAll("/", "."));
            final Field[] declaredFields = implClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                if (implMethodName.endsWith(declaredField.getName().toUpperCase())) {
                    final Annotation[] annotations = declaredField.getAnnotations();
                    for (Annotation annotation : annotations) {
                        if (an.isInstance(annotation)) {
                            return an.cast(annotation);
                        }
                    }
                }
            }
            final Field[] fields = implClass.getFields();
            for (Field field : fields) {
                if (implMethodName.endsWith(field.getName().toUpperCase())) {
                    final Annotation[] annotations = field.getAnnotations();
                    for (Annotation annotation : annotations) {
                        if (an.isInstance(annotation)) {
                            return an.cast(annotation);
                        }
                    }
                }
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return null;
    }


    public static byte[] serialize(Object object) {
        if (object == null) {
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
        try {
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            oos.flush();
        } catch (IOException ex) {
            throw new IllegalArgumentException("Failed to serialize object of type: " + object.getClass(), ex);
        }
        return baos.toByteArray();
    }

    public static SerializedLambda resolve(FF<?, ?> lambda) {
        try (ObjectInputStream objIn = new ObjectInputStream(new ByteArrayInputStream(serialize(lambda))) {
            @Override
            protected Class<?> resolveClass(ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException {
                return super.resolveClass(objectStreamClass);
            }
        }) {
            final Object o = objIn.readObject();
            return getSerializedLambda((Serializable) o);
        } catch (ClassNotFoundException | IOException e) {
            throw new IllegalArgumentException();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static SerializedLambda getSerializedLambda(Serializable serializable) throws Exception {
        Method writeReplaceMethod = serializable.getClass().getDeclaredMethod("writeReplace");
        writeReplaceMethod.setAccessible(true);
        return (SerializedLambda) writeReplaceMethod.invoke(serializable);
    }

    public interface FF<T, R> extends Function<T, R>, Serializable {
    }
}