首页 > 代码库 > javabean内省

javabean内省

  • 何为JavaBean?
JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性。众所周知,属性名称符合这种模式,其他Java 类可以通过自身机制发现和操作这些JavaBean 属性。
 用户可以使用JavaBean将功能、处理、值、数据库访问和其他任何可以用java代码创造的对象进行打包,并且其他的开发者可以通过内部的JSP页面、Servlet、其他JavaBean、applet程序或者应用来使用这些对象。用户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能,而不用关心任何改变。 有的时候我们也成javabean是什么VO了,什么BTO了,什么polo了,说的都是一个东西
  • JavaBean分类:
JavaBean可分为两种:一种是有用户界面(UI,User Interface)的JavaBean;还有一种是没有用户界面,主要负责处理事务(如数据运算,操纵数据库)的JavaBean。JSP通常访问的是后一种JavaBean。
  • JavaBean规范:
1,JavaBean 类必须是一个公共类,并将其访问属性设置为 public  ,如: public class user{......}
2,JavaBean 类必须有一个空的构造函数:类中必须有一个不带参数的公用构造器
3,一个javaBean类不应有公共实例变量,类变量都为private  ,如: private int id;
4属性应该通过一组存取方法(getXxx 和 setXxx)来访问,一般是IDE(Eclipse、JBuilder) 为属性生成getter/setter 方法
注意:一般JavaBean属性以小写字母开头,驼峰命名格式,相应的 getter/setter 方法是 get/set 接上首字母大写的属性名。例如:属性名为userName,其对应的getter/setter 方法是 getUserName/setUserName。以后在定义个javabean的时候,一定要注意检查属性的大小写,特别是第一个字母。如果首字母大写,也是属性名直接用作 getter/setter 方法中 get/set 的后部分。例如属性名为Name,方法是getName/setName,这样子会找不到属性出错,或者说不存在那个属性,因为默认的属性名是name。

  • 内省是什么?

通过反射的方式访问javabean的技术,我们可以去实现一种通用性。java中也有实现,不过一般不用,那几个类看上去有点繁琐,Jdk中有个api : PropertyDescriptor类,他可以操作Bean和Beaninfo的属性。

1.传统的方式去访问javabean

package linkin;

public class LinkinTest
{
	public static void main(String[] args)
	{
		Linkin linkin = new Linkin();
		linkin.setName("LinkinPark...");
		linkin.setAge(25);
		System.out.println(linkin);
	}

}

class Linkin
{
	private String name;
	private Integer age;

	public Linkin()
	{

	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public Integer getAge()
	{
		return age;
	}

	public void setAge(Integer age)
	{
		this.age = age;
	}

	@Override
	public String toString()
	{
		return "Linkin [name=" + name + ", age=" + age + "]";
	}
	
}

2.使用内省的方式来访问javabean

package linkin;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

public class LinkinTest
{
	public static void main(String[] args) throws Exception
	{
		Linkin linkin = new Linkin();
		//创建属性描述器
		PropertyDescriptor descriptor = new PropertyDescriptor("name", Linkin.class);
		//获得写方法
		Method writeMethod = descriptor.getWriteMethod();
		//调用写方法
		writeMethod.invoke(linkin, "LinkinPark...");
		System.out.println(linkin);
	}

}

class Linkin
{
	private String name;
	private Integer age;

	public Linkin()
	{

	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public Integer getAge()
	{
		return age;
	}

	public void setAge(Integer age)
	{
		this.age = age;
	}

	@Override
	public String toString()
	{
		return "Linkin [name=" + name + ", age=" + age + "]";
	}

}

3.简化书写,实现通用性。这里写一个通用的方法,让属性名称为一个变量,假如属性名很多的话,得到属性名后,就可以遍历,然后给他们一一的赋值,这就是内省的魅力。

如果不用反射,那么传统的方式是不可能实现通用的。

下面代码实现能够为任何的javabean赋任何的值,只有用内省的方法才可以做的到:

package linkin;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

public class LinkinTest
{
	public static void main(String[] args) throws Exception
	{
		Linkin linkin = new Linkin();
		setProperty(linkin, "name", "LinkinPark...");
		setProperty(linkin, "age", 25);
		System.out.println(linkin);
	}

	// 实现一个通用的方法   为任意的一个javabean的任意属性赋任意值
	public static void setProperty(Object bean, String fieldName, Object value) throws Exception
	{
		// 创建属性描述器
		PropertyDescriptor descriptor = new PropertyDescriptor(fieldName, bean.getClass());

		// 获得 写方法
		Method writeMethod = descriptor.getWriteMethod();

		// 调用 写方法
		writeMethod.invoke(bean, value);
	}
}

class Linkin
{
	private String name;
	private Integer age;

	public Linkin()
	{

	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public Integer getAge()
	{
		return age;
	}

	public void setAge(Integer age)
	{
		this.age = age;
	}

	@Override
	public String toString()
	{
		return "Linkin [name=" + name + ", age=" + age + "]";
	}

}


BeanUtils工具包,上面的代码有点底层的,Apache的commons包里面定义了一个这个工具类,里面有这个方法的。

setProperty(bean, name, value),我们在使用这个方法的时候不需要强制属性的类型,他会按照我们定义javabean的时候的类型帮我们放进去的,所以传入的是就传入字符串作为value就可以了。

使用这个方法我们可以将任何request提交的表单封装到对应的javabean。

先获得所有的参数:

Enumeration names = request.getParameterNames();

循环获得里面的每一个参数:

String value =http://www.mamicode.com/ request.getParameter(name);

传入一个类名,跑下反射,获得一个实例:

Object bean=beanClass.newInstance();

使用beanUtils将属性注入到对象中:

BeanUtils.setProperty(bean, name, value);

具体代码比较简单,这里就不贴了。

























javabean内省