All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.linksfield.cube.partnersdk.configuration.EndpointPropertiesProxy Maven / Gradle / Ivy

package net.linksfield.cube.partnersdk.configuration;

import lombok.Data;
import net.linksfield.cube.partnersdk.configuration.url.*;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.Properties;

/**
 * @ClassName EndpointPropertiesProxy
 * @Description 配置文件 代理
 *              自动映射properties中的属性到对应字段中
 * @Author James.hu
 * @Date 2023/3/15
 **/
@Data
public class EndpointPropertiesProxy extends Properties {

    /** 主机地址 */
    private String host;

    private Service service;

    private Usage usage;

    private Sim sim;

    private Sms sms;

    private Cdr cdr;

    private Other other;

    private Mall mall;

    private Orders orders;

    /**
     * 自动匹配配置文件的属性到实例的字段上
     */
    public void bindingField() {
        EndpointPropertiesProxy instance = this;
        instance.host = this.getProperty("host");
        for (Map.Entry entry : super.entrySet()) {
            try {
                bind(instance, instance, entry.getKey().toString(), entry.getValue().toString());
            } catch (Exception e) {
                // 放弃所有错误, 一般是配置文件字段与实例字段不匹配
                e.printStackTrace();
            }
        }
    }


    /**
     * 绑定加载到的属性配置 映射到字段上
     * 如果当前行是 host=https://xxx KEY=VALUE 形式, 搜索当前类中名称为KEY的字段并进行赋值
     * 如果当前行是分段式 service.name=xxxxx MODULE.KEY=VALUE 形式, 从当前类中动态代理一个对应名称的接口 并赋值到对应字段上, 接口中的KEY,VALUE会被缓存到动态代理的Map中
     * @param properties 当前主实例对象
     * @param instance  迭代对象
     * @param key       绑定的字段名
     * @param value     绑定的值
     */
    private void bind(EndpointPropertiesProxy properties, Object instance, String key, String value) throws IntrospectionException, ReflectiveOperationException {
        // 判断properties key是否含有 [.] 如果含有'点', 则向下查找子类和字段
        int pos = key.indexOf('.');
        if (pos > -1) {
            // 子类的名称
            String nextModule = key.substring(0, pos);
            // 子类字段名称
            String nextKey = key.substring(pos + 1);
            // 确保子类实例已初始化 并返回对应子类实例
            Object fieldInstance = createFieldInstance(properties, instance, nextModule);
            // 递归绑定
            bind(properties, fieldInstance, nextKey, value);
        } else {
            // 不还有'点', 进行字段值绑定
            Class instanceClass = instance.getClass();
            // 如果是代理类
            if (Proxy.isProxyClass(instanceClass)) {
                EndpointModuleInvocationHandler invocationHandler = (EndpointModuleInvocationHandler) Proxy.getInvocationHandler(instance);
                invocationHandler.setProperties(key, value);
            } else {
                // 查找对应的字段
                PropertyDescriptor propertyDescriptor = new PropertyDescriptor(key, instanceClass);
                // 获取字段的set方法
                Method writeMethod = propertyDescriptor.getWriteMethod();
                // 赋值
                writeMethod.invoke(instance, value);
            }
        }
    }

    private Object createFieldInstance(EndpointPropertiesProxy properties, Object instance, String field) throws IntrospectionException, ReflectiveOperationException {
        // 读取对应的字段
        Class instanceClass = instance.getClass();
        PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field, instanceClass);
        Method readMethod = propertyDescriptor.getReadMethod();
        Object propertyInstance = readMethod.invoke(instance);
        // 如果字段值是null 则创建一个对象代理
        if (propertyInstance == null) {
            // 创建对应接口的代理
            EndpointModuleInvocationHandler handler = new EndpointModuleInvocationHandler(properties.host);
            Class proxyClass = propertyDescriptor.getPropertyType();
            propertyInstance = Proxy.newProxyInstance(propertyDescriptor.getPropertyType().getClassLoader(), new Class[]{proxyClass}, handler);

            // 赋值到字段上
            Method writeMethod = propertyDescriptor.getWriteMethod();
            writeMethod.invoke(instance, propertyInstance);
        }
        return propertyInstance;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy