SSM(九) 反射的实际应用 - 构建日志对象

简介: 相信做Java的童鞋或多或少都听过反射,这也应该是Java从入门到进阶的必经之路。但是在我们的实际开发中直接使用它们的几率貌似还是比较少的,(除了造轮子或者是Spring Mybatis这些框架外)。所以这里介绍一个在实际开发中还是小有用处的反射实例。

传统日志


有关反射的一些基本知识就不说了,可以自行Google,也可以看下反射入门


日志相信大家都不陌生,在实际开发中一些比较敏感的数据表我们需要对它的每一次操作都记录下来。


先来看看传统的写法:


@Test
    public void insertSelective() throws Exception {
        Content content = new Content() ;
        content.setContent("asdsf");
        content.setCreatedate("2016-12-09");
        contentService.insertSelective(content) ;
        ContentLog log = new ContentLog();
        log.setContentid(content.getContentid());
        log.setContent("asdsf");
        log.setCreatedate("2016-12-09");
        contentLogService.insertSelective(log);
    }


非常简单,就是在保存完数据表之后再把相同的数据保存到日志表中。


但是这样有以下几个问题:


  • 如果数据表的字段较多的话,比如几百个。那么日志表的setter()方法就得写几百次,还得是都写对的情况下。


  • 如果哪天数据表的字段发生了增加,那么每个写日志的地方都得增加该字段,提高了维护的成本。


针对以上的情况就得需要反射这个主角来解决了。


利用反射构建日志


我们先来先来看下使用反射之后对代码所带来的改变:


@Test
    public void insertSelective2() throws Exception {
        Content content = new Content();
        content.setContent("你好");
        content.setContentname("1");
        content.setCreatedate("2016-09-23");
        contentService.insertSelective(content);
        ContentLog log = new ContentLog();
        CommonUtil.setLogValueModelToModel(content, log);
        contentLogService.insertSelective(log);
    }


同样的保存日志,不管多少字段,只需要三行代码即可解决。


而且就算之后字段发生改变写日志这段代码仍然不需要改动。


其实这里最主要的一个方法就是CommonUtil.setLogValueModelToModel(content, log);


来看下是如何实现的;


/**
     * 生成日志实体工具
     *
     * @param objectFrom
     * @param objectTo
     */
    public static void setLogValueModelToModel(Object objectFrom, Object objectTo) {
        Class<? extends Object> clazzFrom = objectFrom.getClass();
        Class<? extends Object> clazzTo = objectTo.getClass();
        for (Method toSetMethod : clazzTo.getMethods()) {
            String mName = toSetMethod.getName();
            if (mName.startsWith("set")) {
                //字段名
                String field = mName.substring(3);
                //获取from 值
                Object value;
                try {
                    if ("LogId".equals(field)) {
                        continue;
                    }
                    Method fromGetMethod = clazzFrom.getMethod("get" + field);
                    value = fromGetMethod.invoke(objectFrom);
                    //设置值
                    toSetMethod.invoke(objectTo, value);
                } catch (NoSuchMethodException e) {
                    throw new RuntimeException(e);
                } catch (InvocationTargetException e) {
                    throw new RuntimeException(e);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }


再使用之前我们首先需要构建好主的数据表,然后new一个日志表的对象。


setLogValueModelToModel()方法中:


  • 分别获得数据表和日志表对象的类类型。


  • 获取到日志对象的所有方法集合。


  • 遍历该集合,并拿到该方法的名称。


  • 只取其中set开头的方法,也就是set方法。因为我们需要在循环中为日志对象的每一个字段赋值。


  • 之后截取方法名称获得具体的字段名称。


  • 用之前截取的字段名称,通过getMethod()方法返回数据表中的该字段的getter方法。


  • 相当于执行了String content = content.getContent();


  • 执行该方法获得该字段具体的值。


  • 利用当前循环的setter方法为日志对象的每一个字段赋值。


  • 相当于执行了log.setContent("asdsf");


其中字段名称为LogId时跳出了当前循环,因为LogId是日志表的主键,是不需要赋值的。


当循环结束时,日志对象也就构建完成了。之后只需要保存到数据库中即可。


总结


反射其实是非常耗资源的,再使用过程中还是要慎用。


其中对method、field、constructor等对象做缓存也是很有必要的。


项目地址:github.com/crossoverJi…

个人博客地址:crossoverjie.top

GitHub地址:github.com/crossoverJi…


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
6天前
|
存储 运维 监控
【Flume】flume 日志管理中的应用
【4月更文挑战第4天】【Flume】flume 日志管理中的应用
|
6天前
|
监控 Serverless 数据库
Serverless 应用引擎常见问题之biphon-education-配置了SLS后一直重启如何解决
Serverless 应用引擎(Serverless Application Engine, SAE)是一种完全托管的应用平台,它允许开发者无需管理服务器即可构建和部署应用。以下是Serverless 应用引擎使用过程中的一些常见问题及其答案的汇总:
31 5
|
6天前
|
监控 安全 数据可视化
中间件应用日志记录和监控
【5月更文挑战第1天】中间件应用日志记录和监控
24 3
中间件应用日志记录和监控
|
6天前
|
存储 运维 监控
构建高效可靠的云原生日志监控体系
【4月更文挑战第29天】随着微服务和容器化技术的普及,传统的日志监控方案已难以满足现代云原生应用的需求。本文将探讨如何构建一个既高效又可靠的云原生日志监控体系,涵盖从日志生成、收集、存储到分析的全流程,并重点讨论了利用Fluentd、Elasticsearch、Kibana (EFK) 栈实现日志聚合、搜索和可视化的最佳实践。
|
6天前
|
Dubbo Java Serverless
Serverless 应用引擎操作报错合集之Nacos中nacos启动正常,访问白页,启动日志显示正常如何解决
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
26 0
Serverless 应用引擎操作报错合集之Nacos中nacos启动正常,访问白页,启动日志显示正常如何解决
|
6天前
|
监控 JavaScript Java
|
6天前
|
运维 Java Devops
云效产品使用报错问题之自定义环境构建没有日志,也没有报错,如何解决
本合集将整理呈现用户在使用过程中遇到的报错及其对应的解决办法,包括但不限于账户权限设置错误、项目配置不正确、代码提交冲突、构建任务执行失败、测试环境异常、需求流转阻塞等问题。阿里云云效是一站式企业级研发协同和DevOps平台,为企业提供从需求规划、开发、测试、发布到运维、运营的全流程端到端服务和工具支撑,致力于提升企业的研发效能和创新能力。
云效产品使用报错问题之自定义环境构建没有日志,也没有报错,如何解决
|
6天前
|
存储 API 持续交付
云效产品使用报错问题之使用自定义镜像构建,看不到构建日志要如何解决
本合集将整理呈现用户在使用过程中遇到的报错及其对应的解决办法,包括但不限于账户权限设置错误、项目配置不正确、代码提交冲突、构建任务执行失败、测试环境异常、需求流转阻塞等问题。阿里云云效是一站式企业级研发协同和DevOps平台,为企业提供从需求规划、开发、测试、发布到运维、运营的全流程端到端服务和工具支撑,致力于提升企业的研发效能和创新能力。
|
6天前
|
存储 Prometheus 监控
Flask监控与日志记录:掌握应用运行状况
【4月更文挑战第16天】本文介绍了在Flask应用中实现监控和日志记录的方法,以确保应用稳定性和问题排查。推荐使用Prometheus、Grafana、New Relic或Flask-MonitoringDashboard等工具进行监控,并通过Python的logging模块记录日志。监控集成涉及安装配置工具、添加监控代码,而日志管理则需要集中存储和使用分析工具。安全是关键,要防止未授权访问和数据泄露,避免记录敏感信息。监控和日志记录有助于提升应用性能和用户体验。
|
6天前
|
存储 SQL Serverless
Serverless 应用引擎常见问题之应用下的【应用事件】以及企业级特性下的【事件中心】没有日志如何解决
Serverless 应用引擎(Serverless Application Engine, SAE)是一种完全托管的应用平台,它允许开发者无需管理服务器即可构建和部署应用。以下是Serverless 应用引擎使用过程中的一些常见问题及其答案的汇总:
51 0