程序员之路

重构 -- Java反射机制简单使用

2019-03-29  本文已影响0人  一波怼

一、背景

最近在开发中写了一些功能重复的方法,这些方法唯一不同的地方就是入参都是比较类似的bean,只是为了区分不同的使用场景,创建了多个结构组成类似的多个bean,然后在处理每一个bean的时候都单独写了一个私有方法,具体场景看下面代码。

二、重构前

工具类

/**
 * @author 一波怼
 * @date 2019/3/29
 **/
@Slf4j
public class JaxbUtil {
    public static String convertBeanToXml(Object obj) throws Exception {
        JAXBContext context = JAXBContext.newInstance(obj.getClass());
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
        StringWriter writer = new StringWriter();
        writer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        marshaller.marshal(obj, writer);
        return writer.toString();
    }
}

要转换的bean

/**
 * @author 一波怼
 * @date 2019/3/29
 **/
@Data
@XmlRootElement(name = "header")
@XmlAccessorType(XmlAccessType.FIELD)
public class RequestHeader {
    @XmlElement
    private String type;

    @XmlElement
    private String encoding;
}

@Data
@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
public class CommonRequest {
    @XmlElement
    private RequestHeader header;

    @XmlElement
    private CommonRequestBody body;
}

@Data
@XmlRootElement(name = "body")
@XmlAccessorType(XmlAccessType.FIELD)
public class CommonRequestBody {
    @XmlElement
    private String param1;

    @XmlElement
    private String param2;

    public CommonRequestBody() {
    }

    public CommonRequestBody(String param1, String param2) {
        this.param1 = param1;
        this.param2 = param2;
    }
}

@Data
@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
public class UserRequest {
    @XmlElement
    private RequestHeader header;

    @XmlElement
    private UserRequestBody body;
}

@Data
@XmlRootElement(name = "body")
@XmlAccessorType(XmlAccessType.FIELD)
public class UserRequestBody {
    @XmlElement
    private String name;

    @XmlElement
    private Integer age;

    public UserRequestBody() {
    }

    public UserRequestBody(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}

测试类

@Slf4j
public class Main {
    public static void main(String[] args) throws Exception{
        RequestHeader header = new RequestHeader();
        header.setEncoding("utf8");
        header.setType("X");

        CommonRequestBody commonRequestBody = new CommonRequestBody("1", "2");
        String commonRequestXml = getCommonRequestXml(commonRequestBody, header);

        UserRequestBody userRequestBody = new UserRequestBody("张三", 10);
        String userRequestXml = getUserRequestXml(userRequestBody, header);
        log.info("commonRequestXml = {}, userRequestXml = {}", commonRequestXml, userRequestXml);
    }

    private static String getCommonRequestXml(CommonRequestBody body, RequestHeader header) throws Exception{
        CommonRequest commonRequest = new CommonRequest();
        commonRequest.setHeader(header);
        commonRequest.setBody(body);

        return JaxbUtil.convertBeanToXml(commonRequest);
    }

    private static String getUserRequestXml(UserRequestBody body, RequestHeader header) throws Exception {
        UserRequest userRequest = new UserRequest();
        userRequest.setHeader(header);
        userRequest.setBody(body);

        return JaxbUtil.convertBeanToXml(userRequest);
    }
}

Main中要获得对应bodyBean转换后的XML格式字符串,每种bodyBean类型都需要单独的方法处理getCommonRequestXml()getUserRequestXml(),存在重复的逻辑。

三、重构后

修改测试类
传入需要得到的xxxRequest.class,通过反射获取实例,通过Field得到成员变量,拼装Getter方法进行赋值,最后调用工具类进行转换。

/**
 * @author 一波怼
 * @date 2019/3/29
 **/
@Slf4j
public class Main {
    public static void main(String[] args) throws Exception {
        RequestHeader header = new RequestHeader();
        header.setEncoding("utf8");
        header.setType("X");

        CommonRequestBody commonRequestBody = new CommonRequestBody("1", "2");
        UserRequestBody userRequestBody = new UserRequestBody("张三", 10);

        log.info("commonRequestXml = {}, userRequestXml = {}",
                getRequest(commonRequestBody, header, CommonRequest.class),
                getRequest(userRequestBody, header, UserRequest.class));
    }

    private static String getRequest(Object body,
                                     RequestHeader header,
                                     Class<?> requestClass) throws Exception {
        Object request = requestClass.newInstance();
        Field[] declaredFields = requestClass.getDeclaredFields();
        for (Field field : declaredFields) {
            String fieldName = field.getName();
            String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
            Method method;
            if (StringUtils.equals(fieldName, "header")) {
                method = requestClass.getMethod(methodName, header.getClass());
                method.invoke(request, header);
            } else if (StringUtils.equals(fieldName, "body")) {
                method = requestClass.getMethod(methodName, body.getClass());
                method.invoke(request, body);
            }
        }
        return JaxbUtil.convertBeanToXml(request);
    }
}
上一篇 下一篇

猜你喜欢

热点阅读