频道栏目
首页 > 资讯 > 其他 > 正文

内省+反射(简单应用实现原理)

17-01-02        来源:[db:作者]  
收藏   我要投稿

内省+反射(简单应用实现原理):当我们需要封装从页面传递到后台的请求参数时,简单的方式就是使用一个工具类帮我们封装,省很多力气,还不容易出错。那接下来就简单介绍下这个BeanUtils工具类的实现原理,顺便重温下java内省机制。

BeanUtils的底层是使用java内省机制完成的,而内省的实现要依赖java 的反射机制

首先说明:为什么map中的value值的格式为String[]数组类型,因为表单中可能存在多选框,所以需要数组接收。

一:那么首先使用java反射来完成请求参数的封装

package com.wanghang.domain;

/**
 * User模型类
 * 
 * @author Hang.W
 * @version 1.0, 2016-12-24 12:53:10
 */
public class UserModel {

	private String username;

	private String password;

	public UserModel() {
	}

	public UserModel(String username, String password) {
		this.username = username;
		this.password = password;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public String toString() {
		return "UserModel [username=" + username + ", password=" + password
				+ "]";
	}

}
package com.wanghang.reflect;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import com.wanghang.domain.UserModel;

/**
 * 使用java反射机制来完成参数封装
 * 
 * @author Hang.W
 * @version 1.0, 2016-12-24 12:42:04
 */
public class Reflect {

	/**
	 * 通过反射注入参数
	 * 
	 * @throws Exception
	 */
	@Test
	public void reflect() throws Exception {
		// 创建一个Map集合,封装(假设从页面传递的)参数
		Map map = new HashMap();
		map.put("username", new String[] {"张三"});
		map.put("password", new String[] {"123"});
		
		// 创建User模型类
		UserModel userModel = new UserModel();
		
		// 获取map中所有的key
		Set keys = map.keySet();
		
		// 通过反射获取UserModel类中所有的方法(包括私有)
		Method[] methods = userModel.getClass().getDeclaredMethods();
		
		// 判断方法名是否和 "set" + 从页面表单获取name属性的值相同
		for(String key : keys) {
			// 从页面上获取的name属性的值加上"set"
			String newKey = "set" + key;
			for (Method method : methods) {
				// 获取方法名
				String name = method.getName();
				// 判断
				if(newKey.equalsIgnoreCase(name)) {
					// 相同,反射执行方法 invoke("对象", "参数")
					method.invoke(userModel, map.get(key)[0]);
				}
			}
		}
		System.out.println(userModel);
	}
}

简单说明:

我们要封装从表单标签(例:用户名:)传递的参数,那么我们就可以从表单中name属性作为切入点,使用反射机制,封装参数。

具体实现:

1.首先获取表单标签name属性中的值,

2.获取对象模型类中的所有方法

3.进行比对,执行setXXX方法进行参数封装

二:使用内省方式封装参数

package com.wanghang.reflect;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import com.wanghang.domain.UserModel;

/**
 * 使用内省机制完成参数封装
 * 
 * @author Hang.W
 * @version 1.0, 2016-12-24 14:32:30
 */
public class Introspect {

	/**
	 * 通过内省封装参数
	 * 
	 * @throws Exception
	 */
	@Test
	public void introspect() throws Exception {
		// 创建一个Map集合,封装(假设从页面传递的)参数
		Map map = new HashMap();
		map.put("username", new String[] {"张三"});
		map.put("password", new String[] {"123"});
		
		// 创建User模型类
		UserModel userModel = new UserModel();
		
		// 获取BeanInfo对象
		BeanInfo beanInfo = Introspector.getBeanInfo(UserModel.class);
		
		// 通过BeanInfo对象获取所有的属性描述器(说白了,就是获取所有的属性)
		PropertyDescriptor[] propertyDescriptor = beanInfo.getPropertyDescriptors();
		for (PropertyDescriptor prop : propertyDescriptor) {
			//System.out.println(prop);
			// 通过属性描述器,获取写方法
			Method writeMethod = prop.getWriteMethod();
			if(writeMethod != null) {
				// 获取所有属性的名字(与表单标签中填写的相同)
				String name = prop.getName();
				// 反射执行方法
				writeMethod.invoke(userModel, map.get(name)[0]);
			}
		}
		System.out.println(userModel);
	}
}

简单说明:

内省机制,要通过属性描述器将类中的所有属性获取到,然后再进行比对,封装参数

具体实现:

1.获取属性描述器对象

2.通过属性描述器对象获取模型类中所有属性

3.获取模型类中set()方法

4.获取表单标签中name属性的值

5.进行比对,反射执行方法,封装参数

相关TAG标签
上一篇:Linux内核
下一篇:java日志框架slf4j与log4j
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站