美文网首页程序员之路
重构 -- 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反射机制简单使用

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