利用反射操作bean的属性和方法
今天在开发中碰到这样一个场景:当请求添加项目下的目录时,传过来的是一个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的属性和方法的更多相关文章
- 利用 spring bean 的属性 init-method 解决因为数据库连接没有初始化而导致首次点击页面超慢的问题
		问题的描述: 一个项目,涉及到了 两个数据源,分别使用的是 两个不同的 数据库连接池,其中一个是 poxool 连接池,问题在于,spring在启动时,只初始化其中的一个 数据库连接池中的数据库连接, ... 
- Spring框架bean的配置(2):SpEL:引用 Bean、属性和方法。。。
		将这些架包放入在工程目录下建立的lib文件夹里,并解压 commons-logging-1.1.1 spring-aop-4.0.0.RELEASE spring-beans-4.0.0.RELEAS ... 
- final修饰的类,其属性和方法默认是被final修饰的吗?
		在论坛上,看到一个问题,当然,各位聪明的客官想必已经知道问题是什么了,嘿嘿,没错就是文章的标题:final修饰的类,其属性和方法默认是被final修饰的吗? 老实说,刚开始看到这个问题的时候,有点懵. ... 
- 7 -- Spring的基本用法 -- 10... 获取其他Bean的属性值;获取Field值;获取任意方法的返回值
		7.10 高级依赖关系配置 组件与组件之间的耦合,采用依赖注入管理:但基本类型的成员变量值,应直接在代码中设置. Spring支持将任意方法的返回值.类或对象的Field值.其他Bean的getter ... 
- 使用外部属性文件配置Bean以及Bean的生命周期方法
		1.使用外部属性文件配置Bean 在配置文件里配置 Bean 时, 有时需要在 Bean 的配置里混入系统部署的细节信息(例如: 文件路径, 数据源配置信息等). 而这些部署细节实际上需要和 Bean ... 
- java利用反射访问类的私有(private)属性及方法
		Java语言中,在一个类中,为了不让外界访问到有的属性和方法,通常将其设置为private,用正常的方式(对象名.属性名,对象名.方法名)将无法访问此属性与方法,但有没有其他方法可以访问呢?答案是有的 ... 
- 普通Java类获取spring 容器的bean的5种方法
		方法一:在初始化时保存ApplicationContext对象方法二:通过Spring提供的工具类获取ApplicationContext对象方法三:继承自抽象类ApplicationObjectSu ... 
- spring(四):spring中给bean的属性赋值
		spring中给bean的属性赋值 xml文件properties标签设置 <bean id="student" class="com.enjoy.study.ca ... 
- Spring Ioc源码分析系列--容器实例化Bean的四种方法
		Spring Ioc源码分析系列--实例化Bean的几种方法 前言 前面的文章Spring Ioc源码分析系列--Bean实例化过程(二)在讲解到bean真正通过那些方式实例化出来的时候,并没有继续分 ... 
随机推荐
- java的linux命令
			1.查找文件find / -name filename.txt 根据名称查找/目录下的filename.txt文件.find . -name “*.xml” 递归查找所有的xml文件2.查看一个程序是 ... 
- Maven依赖解析
			本文将记录Maven工程中依赖解析机制,内容包括: Maven依赖基本结构 从仓库解析依赖的机制 依赖传递性解析实例 1. Maven依赖基本结构 上篇文章记录了Maven依赖的聚合与继承,POM中依 ... 
- ImageMagick图片服务器
			1.前置准备工具如下: nodejs express(nodejs mvc框架) body-parser(express middleware) gm(nodejs中用来处理图片的) uuid(nod ... 
- 判断pdf、word文档、图片等文件类型(格式)、大小的简便方法
			判断pdf.word文档.图片等文件类型(格式).大小的简便方法 很久没发文了,今天有时间就写一下吧. 关于上传文件,通常我们都需要对其进行判断,限制上传的类型,如果是上传图片,我们甚至会把图片转化成 ... 
- Oracle常用的数值函数,日期函数
			---恢复内容开始--- 数值函数 常用的处理数值的函数有如下: No. 函数名 含义 1 round(x[,y]) 返回四舍五入后的值 2 trunc(x[,y]) 不会四舍五入 3 mod(x,y ... 
- alex python of day1
			Print("hello word!")#打印hello word!向python世界发生第一声呐喊,仪式很重要 定义变量 name="Alex Li" nam ... 
- SQL---约束---add constraint方法添加约束
			1.主键约束: 格式为:alter table 表格名称 add constraint 约束名称 增加的约束类型 (列名) 例子:alter table emp add constraint ppp ... 
- JavaEE中的MVC(二)Xml配置实现IOC控制反转
			毕竟我的经验有限,这篇文章要是有什么谬误,欢迎留言并指出,我们可以一起讨论讨论. 我要讲的是IOC控制反转,然后我要拿它做一件什么事?两个字:"解耦",形象点就是:表明当前类中需要 ... 
- python之列表(list)的使用方法介绍
			python之列表(list)介绍 在python的使用过程中,我们经常会用到列表,然而经常会遇到疑惑,下面我将详细介绍下列表使用方法. 一.列表 列表经常用到的功能使增.删.改和查功能. 1. 增 ... 
- ubuntu指令记录
			记录一些指令,便于查看使用. 1.sudo -以其他身份运行命令,预设身份为root. 2.ctrl+alt+T打开终端(命令行窗口) 3.如何判断linux系统是32位还是64位,指令:getcon ... 
