美文网首页程序员之路
重构 -- Java反射机制简单使用

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

作者: 一波怼 | 来源:发表于2019-03-29 20:32 被阅读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);
    }
}

相关文章

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

    一、背景 最近在开发中写了一些功能重复的方法,这些方法唯一不同的地方就是入参都是比较类似的bean,只是为了区分不...

  • Java反射

    简单总结下什么是Java反射,怎么使用。 Java反射机制 反射就是指JVM运行期,获取指定类所有的属性和方法的一...

  • Android 编译时注解 —— 语法详解

    java Type 详解 java 反射机制详解 注解使用入门(一) Android 自定义编译时注解1 - 简单...

  • Java反射机制

    最近看了一下想学习一下Retrofit,发现其中使用到了Java的反射机制,虽然之前也简单使用过Java的反射,但...

  • Java反射机制入门

    Java反射机制入门 一、什么是反射 JAVA反射机制(The JAVA reflection mechanism...

  • 反射之一

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • 反射之二

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • Scala学习笔记(二)

    使用classOf[T]或者getClass()来获得类的反射。scala的本身没有反射,而使用java的反射机制...

  • Java基本知识

    java反射机制 大白话说Java反射:入门、使用、原理[https://www.cnblogs.com/chan...

  • Java基础之反射

    Java-Reflect Class类的使用 方法的反射 成员变量的反射 构造函数的反射 Java类加载机制 一、...

网友评论

    本文标题:重构 -- Java反射机制简单使用

    本文链接:https://www.haomeiwen.com/subject/mscrbqtx.html