Using Java reflection principle and properties configuration file to set the field of dynamic update policy

Recently encountered such a demand at work: the vehicle information data on the cloud to synchronize the local vehicle information and data, but some fields are not necessarily local data to be updated, so business people want to achieve from a can define a policy update field.
Based on the above requirements, consider the number of fields you want to update existing systems and business logic implementation, combined with the actual situation of the system, the final decisionUsing Java reflection principle and properties set dynamically update the configuration file field

Ideas are as follows:
1、不更新的字段配置在 properties 文件中 配置为 className=fieldName1,fieldName2,..., full path name for the class className
2、从配置文件读取给定类的不需要更新的字段配置信息
3、实现一个工具类,获取 2 中的配置的类的相关字段,并找到该字段对应的setter、getter方法,利用反射调用setter、getter方法,用本地的数据去覆盖之前从云上获取的数据
4、在原有的业务逻辑代码中加入 3 中工具类的调用

Code is implemented as follows:
1, tools:

/**
 * @date: 2019/4/29 17:32
 * @description: 使用配置文件获取当前Bean对象的某些字段是否要被更新,根据配置文件配置信息将当前Bean对象不需要更新的字段重置为对应的
 *               本地Bean对象中的字段,实现字段更新的可配置化操作
 */
public class BeanFieldResetUtils {
    /** 配置某个类不更哪些字段的配置文件 */
    private static final String PROPERTIES_FILE_NAME = "notUpdateBeanFields.properties";
    /**
     * 重置当前Bean的属性方法
     * @param target 要被重置的Bean
     * @param source 用来重置的Bean
     */
    public static void resetBeanFields(Object target,Object source){
        // 获取类的全路径名
        String classPathName = target.getClass().getName();
        // 不用更新的字段List
        List<String> notUpdateFields = BeanFieldResetUtils.getPropertiesContext(classPathName);
        for (String field : notUpdateFields) {
            try {
                // 获取当前字段对应的方法描述
                PropertyDescriptor descriptor = new PropertyDescriptor(field, target.getClass());
                // 获得写方法(setter方法)
                Method setMethod = descriptor.getWriteMethod();
                // 获得读方法(getter方法)
                Method getMethod = descriptor.getReadMethod();
                // 使用反射调用对象的 setter、getter 方法
                setMethod.invoke(target,getMethod.invoke(source));
            } catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 根据类的全路径名获取当前类配置的无需更新的字段
     * @param classPathName
     * @return
     */
    private static List<String> getPropertiesContext(String classPathName){
        Properties properties = new Properties();
        List<String> notUpdateFieldList = null;
        try {
            // 获取当前类路径下的指定配置文件的内容
            ClassPathResource resource = new ClassPathResource(BeanFieldResetUtils.PROPERTIES_FILE_NAME);
            properties.load(resource.getInputStream());
            // 获取配置文件中指定的类的内容
            String property = properties.getProperty(classPathName);
            if (StringUtils.isNotBlank(property)){
                // 分割不需要更新的字段
                String[] notUpdateFields = property.split(",");
                // 将字符串数组转成一个List
                notUpdateFieldList = Arrays.asList(notUpdateFields);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return notUpdateFieldList;
    }
}

2, the configuration file:

# 这里写不用更新的 Bean 的字段

### 格式为:全类名=字段1,字段2,...
com.test.model.VehicleDetail=vehicleType,transportType

Guess you like

Origin blog.csdn.net/weixin_44290425/article/details/89840052
Recommended