天天看点

利用动态配置表、反射来动态给Model类添加属性

1.给model添加对应的映射属性

import com.alibaba.fastjson.JSON;
import com.chinadep.paidan.dataroute.mappingBean.Person;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.*;

@Data
public class ReflectAttrUtil {
    private static final Logger logger = LoggerFactory.getLogger(ReflectAttrUtil.class);

    public String source_type;
    public String case_no;
    public String origin_case_no;
    public String origin_id;
    public String address; //
    public String level; //
    public String leve2; //
    public String leve3; //
    public String leve4; //
    public Person person;

    private static final Map<String, Class<?>> primitiveToWrappers = new HashMap();

    // 反射动态属性添加Class
    static{
        primitiveToWrappers.put("boolean", Boolean.class);
        primitiveToWrappers.put("char", Character.class);
        primitiveToWrappers.put("double", Double.class);
        primitiveToWrappers.put("float", Float.class);
        primitiveToWrappers.put("int", Integer.class);
        primitiveToWrappers.put("long", Long.class);
        primitiveToWrappers.put("string", Long.class);
        primitiveToWrappers.put("list", ArrayList.class);
        primitiveToWrappers.put("string", String.class);
    }

    private final static Class<?> getClassBytype(String type){
        return primitiveToWrappers.getOrDefault(type, String.class);
    }

    /***
     * 配置表中去除,字段映射关系  attrname->attrtype->mappingname->attrvalue
     */
    private final static HashMap<String, String> map = new HashMap<String, String>() {{
        put("a1", "source_type");
        put("a2", "case_no");
        put("a3", "origin_case_no");
        put("a4", "origin_id");
        put("a5", "address");
        put("a6", "level");
        put("a7", "leve2");
        put("a8", "leve3");
        put("a9", "leve6");
    }};


    /***
     * 组装model
     * @param object
     * @param valueMap
     * @return
     */
    private static Object componentModel(Object object, Map<String, Object> valueMap){
        // 不存在的属性, 动态添加
        HashMap addClzMap = new HashMap();
        HashMap addValMap = new HashMap();

        for (String key : valueMap.keySet()) {
            String attrName = map.get(key);

            try {
                Field field = object.getClass().getDeclaredField(attrName);
                // 值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查;
                // 实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问 ;
                // 由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的 
                field.setAccessible(true);
                // 存在的属性映射,直接setval
                field.set(object, valueMap.get(key));

            } catch (Exception e) {
                // 原始model中不存在属性,动态添加
                addClzMap.put(attrName, getClassBytype("string"));
                addValMap.put(attrName, attrName);
                logger.info("属性-" + attrName + "不存在");
            }
        }

//        System.out.println(object);
        System.out.println(JSON.toJSONString(object));
        System.out.println("---------------------");

        Object res = null;
        try {
            if(Objects.nonNull(addClzMap)) {
                // 核心方法dynamicClass() 动态添加属性
                res = DynamicAttrUtil.dynamicClass(object, addClzMap, addValMap);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return res;
    }

    public static void main(String[] args) {
        Map<String, Object> map1 = new HashMap<>();
        map1.put("a1", "a1");
        map1.put("a2", "a2");
        map1.put("a3", "a3");
        map1.put("a4", "a4");
        map1.put("a5", "a5");
        map1.put("a6", "a6");
        map1.put("a7", "a7");
        map1.put("a8", "a8");
        map1.put("a9", "a9");

        ReflectAttrUtil reflectAttrUtil = new ReflectAttrUtil();
        Person person = new Person();
        person.setId("personid");
        person.setName("personname");
        reflectAttrUtil.setPerson(person);

//        Field[] fields = reflectAttrUtil.getClass().getDeclaredFields();
//        for(Field field : fields) {
//            System.out.println(field.getName());
//            System.out.println(field.getType());
//            System.out.println(field.getAnnotatedType());
//            System.out.println("---------------------");
//        }

        Object res = componentModel(reflectAttrUtil, map1);

//        System.out.println(res);
        System.out.println(JSON.toJSONString(res));
    }

}
           

2.动态添加属性值

import org.springframework.cglib.beans.BeanGenerator;
import org.springframework.cglib.beans.BeanMap;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class DynamicAttrUtil {
    /**
     *
     * @param object   旧的对象带值
     * @param addMap   动态需要添加的属性和属性类型
     * @param addValMap  动态需要添加的属性和属性值
     * @return  新的对象
     * @throws Exception
     */
    public static Object dynamicClass(Object object, HashMap addMap, HashMap addValMap) throws Exception {
        HashMap returnMap = new HashMap();
        HashMap typeMap = new HashMap();

        Class<?> type = object.getClass();
        BeanInfo beanInfo = Introspector.getBeanInfo(type);
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (int i = 0; i < propertyDescriptors.length; i++) {
            PropertyDescriptor descriptor = propertyDescriptors[i];
            String propertyName = descriptor.getName();
            if (!propertyName.equals("class")) {
                Method readMethod = descriptor.getReadMethod();
                Object result = readMethod.invoke(object);
                //可以判断为 NULL不赋值
                returnMap.put(propertyName, result);
                typeMap.put(propertyName, descriptor.getPropertyType());
            }
        }

        returnMap.putAll(addValMap);
        typeMap.putAll(addMap);

        //map转换成实体对象
        DynamicBean bean = new DynamicBean(typeMap);
        //赋值
        Set keys = typeMap.keySet();
        for (Iterator it = keys.iterator(); it.hasNext(); ) {
            String key = (String) it.next();
            bean.setValue(key, returnMap.get(key));
        }
        Object obj = bean.getObject();
        return obj;
    }
}

class DynamicBean {
    private Object object = null; //动态生成的类
    private BeanMap beanMap = null; //存放属性名称以及属性的类型

    public DynamicBean() {
        super();
    }

    public DynamicBean(Map propertyMap) {
        this.object = generateBean(propertyMap);
        this.beanMap = BeanMap.create(this.object);
    }

    /**
     * @param propertyMap
     * @return
     */
    private Object generateBean(Map propertyMap) {
        BeanGenerator generator = new BeanGenerator();
        Set keySet = propertyMap.keySet();
        for (Iterator i = keySet.iterator(); i.hasNext(); ) {
            String key = (String) i.next();
            generator.addProperty(key, (Class) propertyMap.get(key));
        }
        return generator.create();
    }

    /**
     * 给bean属性赋值
     *
     * @param property 属性名
     * @param value    值
     */
    public void setValue(Object property, Object value) {
        beanMap.put(property, value);
    }

    /**
     * 通过属性名得到属性值
     *
     * @param property 属性名
     * @return 值
     */
    public Object getValue(String property) {
        return beanMap.get(property);
    }

    /**
     * 得到该实体bean对象
     *
     * @return
     */
    public Object getObject() {
        return this.object;
    }
}