今天在开发中碰到这样一个场景:当请求添加项目下的目录时,传过来的是一个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. 为什么选择使用Sass而不是Less?

    这篇文章主要解答以下几个问题,供前端开发者的新手参考. 1.什么是Sass和Less? 2.为什么要使用CSS预处理器? 3.Sass和Less的比较 4.为什么选择使用Sass而不是Less? 什么 ...

  2. [转载] 2 分钟读懂大数据框架 Hadoop 和 Spark 的异同

    转载自https://www.oschina.net/news/73939/hadoop-spark-%20difference 谈到大数据,相信大家对Hadoop和Apache Spark这两个名字 ...

  3. [转载] Java集合框架之小结

    转载自http://jiangzhengjun.iteye.com/blog/553191 1.Java容器类库的简化图,下面是集合类库更加完备的图.包括抽象类和遗留构件(不包括Queue的实现): ...

  4. 获取IP-linux(经典-实用)

    Linux系统获取网卡ip 1.正宗的有6种取ip的方法 sed(3) +awk(2)+egrep(1) sed(替换):   ( )\1   [^0-9.]   掐头|去尾 awk(分隔符):   ...

  5. javascript执行机制

    文的目的就是要保证你彻底弄懂javascript的执行机制,如果读完本文还不懂,可以揍我. 不论你是javascript新手还是老鸟,不论是面试求职,还是日常开发工作,我们经常会遇到这样的情况:给定的 ...

  6. 《java.util.concurrent 包源码阅读》26 Fork/Join框架之Join

    接下来看看调用ForkJoinTask的join方法都发生了什么: public final V join() { // doJoin方法返回该任务的状态,状态值有三种: // NORMAL, CAN ...

  7. 网页的居中显示,使用了margin、clear:both

    很久没写过页面了,现在写起来也觉得捡起来还是挺快的. 当时遇到了这样的问题,我有一个大的div包涵了整个网站,有网页头部,中部还有底部.头部就是一个标题,中部就是几张图片跟文字排版,结果左右两边的图片 ...

  8. 读Kafka Consumer源码

    最近一直在关注阿里的一个开源项目:OpenMessaging OpenMessaging, which includes the establishment of industry guideline ...

  9. Linux系统bashshell之别名

    1.别名的查看: 命令查看:alias 配置文件查看:cat  ~/.bashrc 2:别名设置: alias  cdnet="cd  /etc/sysconfig/network-scri ...

  10. 安装 Qt 及所需 gcc 等

    嫌麻烦,下载离线安装包一次性装好 Qt 及 Qt Creator (Community) Qt 安装包下载地址 http://download.qt.io/official_releases/qt/ ...