JAVA-自省机制-java-bean
目录
JAVA 自省机制 java bean
//Java Bean
1 Java对象,是有一定约定的对象
2 同一外观,为了使用方便
3 Java Bean的约定
①类一定有无参数构造器(直接创建对象,子类继承时候方便直接调用父类无参构造器)
②对象属性使用get set方法访问。
get set方法访问的属性称为Bean属性
③一定实现序列话接口(方便对象序列化)
④必须在包中定义
4 软件开发中建议采用Java Bean规则定义Bean
5 Java提供了一套java.beans API,对反射进行了封装,专门为Java Bean设计的API,这套API称为java自省api
作用:方便访问Java 的Bean属性方法
案例:
实现Bean属性的复制操作。
@Test
public void testBeans() throws IntrospectionException{
//实现Bean属性的复制功能
Person tom = new Person(2, "Tom", false);
PersonVO vo = new PersonVO();
//将tom对象中的属性,复制到 vo对象中(如果有对应属性就进行复制操作)
beanCopy(tom, vo);
System.out.println(vo);// Tom false
}
public void beanCopy(Object src, Object dec) {
try{
//分析 srcBean的bean属性
BeanInfo srcBeanInfo = Introspector.getBeanInfo(src.getClass());
BeanInfo decBeanInfo = Introspector.getBeanInfo(dec.getClass());
//将目标的bean 写出方法保存在散了表, 用于优化查找
HashMap<String, Method> map = new HashMap<String, Method>();
PropertyDescriptor[] descriptorSrc = decBeanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : descriptorSrc) {
String name = property.getName();
Method method = property.getWriteMethod();
//写出方法(set) 是肯能不存在的!
if (method!=null) {
map.put(name, method);
}
}
System.out.println(map);
//迭代每个srcBean的属性
PropertyDescriptor[] descriptorDec = srcBeanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : descriptorDec) {
String name = property.getName();
Method getMethod = property.getReadMethod();
Method setMethod = map.get(name);
if(getMethod!=null && setMethod != null){
//执行 srcBean的get方法获取值
Object val = getMethod.invoke(src);
//执行 tagBean的set方法设置值
setMethod.invoke(dec, val);
}
}
System.out.println("Bean属性复制完毕!");
}catch(IntrospectionException e){
e.printStackTrace();
System.out.println("java Bean 分析失败!");
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class PersonVO implements Serializable{
private String name;
private boolean married;
public PersonVO() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isMarried() {
return married;
}
public void setMarried(boolean married) {
this.married = married;
}
@Override
public String toString() {
return "PersonVO [name=" + name + ", married=" + married + "]";
}
}
class Person implements Serializable{
/** 使用成员变量声明的“对象属性” age*/
private int age;
private String name;
private boolean married;
public Person() {
}
public Person(int age, String name, boolean married) {
super();
this.age = age;
this.name = name;
this.married = married;
}
public String sayHelloTo(Person guy){
return this.name + " say hello to "+ guy.name+"!";
}
/** booelan 类型的Bean属性有两种写法: isMarried == getMarried */
public boolean isMarried() {
return married;
}
public void setMarried(boolean married) {
this.married = married;
}
/** 使用set/get 方法声明的“Bean属性” age */
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Apache.org 提供了常用的通用API,是非常便捷的成品API:commons-beanutils,我们使用commons-beanutils可以很方便的进行编程,commons-beanutils包依赖 commons-logging-1.2 ,所以我们要把这两个包都要导进工程。若使用这个jar包业务逻辑类与值对象类都必须是public的