今天在开发中碰到这样一个场景:当请求添加项目下的目录时,传过来的是一个IndexModel,这个Model里有关于这个目录字段的详细信息,包括基础报表,实时,漏斗等信息(这些字段类型都是boolean),对应于页面上生成目录的多选框。现要将这些配置存入数据库,在数据库中存的是这个项目下的目录,比如说在页面勾选了基础报表这个选择框,就会在数据库中的menu表插入一条数据记录这个配置。这样一来,就需要对传递过来的这个IndexModel类的属性值进行判断,再决定插入数据库的信息。

下面是IndexModel这个model的基本属性:

 public class IndexModel {
private Boolean basic_report; //基础报表
private Boolean realtime; //实时
private Boolean event; //事件
private Boolean retain;// 留存
private Boolean funnel; //漏斗
private Boolean explore; //探索
private Boolean grouping; //分组
private Boolean user_portrait; //用户画像
private Boolean log; //日志 //setters and getters ..
}

当某个属性为true时,则就会将这个属性配置进数据库,当这个属性为false时,则不会进行任何操作。

由此,我想到了利用Java反射,遍历这个类的属性,然后获取到这个属性的名字和值判断,再映射成数据库表的字段,插入到数据库中去。

我们先上解决方案代码:

  Field[] fields = IndexModel.class.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field f = fields[i];
f.setAccessible(true); // 设置这些属性是可以访问的
try {
if(f.getGenericType().toString().endsWith("Boolean") && (Boolean) f.get(indexModel) == true) { // 得到此属性的值
IndexDto indexDto = parseIndexModelToDto(indexModel, f.getName());
projectService.addIndex(indexDto);
}
} catch (IllegalAccessException e) {
logger.error("属性类型转换异常");
}
}

在代码中先是利用反射获取类的所有对象成员的字段值,在这里由于IndexModel中的属性字段值都是private的,所以,只能使用 getDeclaredFields()获取到这些字段,至于getFields()方法,只能获取到类(及其父类)中的公有成员,这两个方法返回的都是Field类型的数组。

在获取私有成员值之前,必须调用setAccessible(true),否则的话,将会抛出异常:java.lang.IllegalAccessException:  class... can not access ,显示不能获取字段值。

另外,在需要获取成员的类型时,需要调用相应的field的getType()方法,获取field的类型有如下几种方法

  Class<?> type = field.getType();        // 通过这种方式只对普通类型的Field有效,如果该Field的类型是有泛型限制的类型,如Map<String,Integer>类型,则不能准确得到该Field的泛型参数。

  Type type = field.getGenericType();  // 为了获得指定Field的泛型类型,应该使用这个方法来获取指定Field的泛型类型

如果要获取上面对应field的被泛型限制的方法,就需要将上面的type对象强制类型转换成ParameterizedType对象,ParameterizedType代表被参数化的类型,也就是增加了泛型限制的类型,ParameterizedType类提供了两个方法:

getRawType();                            返回被泛型限制的类型;

getActualTypeArguments();        返回泛型参数类型。

然后,要获取成员变量的名称直接使用field.getName(),但是属性值则是field.get(Object),这个object是该field所属的!

最后,要是想为这个成员变量设置值,则需要调用set:field[i].set(indexModel , true);

利用反射操作bean的属性和方法的更多相关文章

  1. 利用 spring bean 的属性 init-method 解决因为数据库连接没有初始化而导致首次点击页面超慢的问题

    问题的描述: 一个项目,涉及到了 两个数据源,分别使用的是 两个不同的 数据库连接池,其中一个是 poxool 连接池,问题在于,spring在启动时,只初始化其中的一个 数据库连接池中的数据库连接, ...

  2. Spring框架bean的配置(2):SpEL:引用 Bean、属性和方法。。。

    将这些架包放入在工程目录下建立的lib文件夹里,并解压 commons-logging-1.1.1 spring-aop-4.0.0.RELEASE spring-beans-4.0.0.RELEAS ...

  3. final修饰的类,其属性和方法默认是被final修饰的吗?

    在论坛上,看到一个问题,当然,各位聪明的客官想必已经知道问题是什么了,嘿嘿,没错就是文章的标题:final修饰的类,其属性和方法默认是被final修饰的吗? 老实说,刚开始看到这个问题的时候,有点懵. ...

  4. 7 -- Spring的基本用法 -- 10... 获取其他Bean的属性值;获取Field值;获取任意方法的返回值

    7.10 高级依赖关系配置 组件与组件之间的耦合,采用依赖注入管理:但基本类型的成员变量值,应直接在代码中设置. Spring支持将任意方法的返回值.类或对象的Field值.其他Bean的getter ...

  5. 使用外部属性文件配置Bean以及Bean的生命周期方法

    1.使用外部属性文件配置Bean 在配置文件里配置 Bean 时, 有时需要在 Bean 的配置里混入系统部署的细节信息(例如: 文件路径, 数据源配置信息等). 而这些部署细节实际上需要和 Bean ...

  6. java利用反射访问类的私有(private)属性及方法

    Java语言中,在一个类中,为了不让外界访问到有的属性和方法,通常将其设置为private,用正常的方式(对象名.属性名,对象名.方法名)将无法访问此属性与方法,但有没有其他方法可以访问呢?答案是有的 ...

  7. 普通Java类获取spring 容器的bean的5种方法

    方法一:在初始化时保存ApplicationContext对象方法二:通过Spring提供的工具类获取ApplicationContext对象方法三:继承自抽象类ApplicationObjectSu ...

  8. spring(四):spring中给bean的属性赋值

    spring中给bean的属性赋值 xml文件properties标签设置 <bean id="student" class="com.enjoy.study.ca ...

  9. Spring Ioc源码分析系列--容器实例化Bean的四种方法

    Spring Ioc源码分析系列--实例化Bean的几种方法 前言 前面的文章Spring Ioc源码分析系列--Bean实例化过程(二)在讲解到bean真正通过那些方式实例化出来的时候,并没有继续分 ...

随机推荐

  1. Java反射机制使用场景

    import java.io.*; import java.util.Properties; /*问题描述:存在一个主板--已经定义好,不想修改其代码,还想在主板上面增加一些其他功能? *问题解决方法 ...

  2. 快速自检电脑是否被黑客入侵过(Windows版)

    我们经常会感觉电脑行为有点奇怪, 比如总是打开莫名其妙的网站, 或者偶尔变卡(网络/CPU), 似乎自己"中毒"了, 但X60安全卫士或者X讯电脑管家扫描之后又说你电脑" ...

  3. SSM所需的jar

    首先去找struts的. http://struts.apache.org/ 下载最新的struts 2.3.7. http://www.springsource.org/spring-framewo ...

  4. 张高兴的 Xamarin.Forms 开发笔记:TapGestureRecognizer 的简单介绍与应用

    最近很少写应用了,一直在忙关于 ASP.NET 的东西(哈欠...).抽点时间对 TapGestureRecognizer 做点总结. 一.简介 TapGestureRecognizer 就是对 Ta ...

  5. 《Metasploit魔鬼训练营》第四章(下)

    p163 XSSF 默认kali 2.0中没有xssf,先下载:https://code.google.com/archive/p/xssf/downloads 将下载下来的zip文件解压,将其中的d ...

  6. 常用接口简析2---IComparable和IComparer接口的简析

    常用接口的解析(链接) 1.IEnumerable深入解析 2.IEnumerable.IEnumerator接口解析 3.IList.IList接口解析 默认情况下,对象的Equals(object ...

  7. C#设计模式之十七观察者模式(Observer Pattern)【行为型】

    一.引言   今天是2017年11月份的最后一天,也就是2017年11月30日,利用今天再写一个模式,争取下个月(也就是12月份)把所有的模式写完,2018年,新的一年写一些新的东西.今天我们开始讲& ...

  8. Unity3D寻路导航烘焙

    在初次进行3D(三维)游戏体验中,避免不了对游戏有生疏的情况,因此在游戏中一般会插入新手指导.自动寻路.导航地图等AI人工智能技术到游戏中,方便玩家更快体验,为了玩家的体验更好,Unity3D寻路导航 ...

  9. Shell编程基础篇

    1.1 前言 1.1.1 为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应用软件的核心大都涉及Shell脚 ...

  10. CNN网络介绍与实践:王者荣耀英雄图片识别

    欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者介绍:高成才,腾讯Android开发工程师,2016.4月校招加入腾讯,主要负责企鹅电竞推流SDK.企鹅电竞APP的功能开发和技术优化工作 ...