JavaBean是描述Java的软件组件模型,在Java模型中,通过JavaBean可以无限扩充Java程序的功能,通过JavaBean的组合可以快速的生成新的应用程序。那javaBean是如何工作的?下面来我们就来给大家讲解一下javaBean工作原理。
一,bean的定义:
一个Javabean实际上就是一个Java类,遵循如下规则:
(1)有一个默认的无参构造函数(这点在pring中不是必须的, spring可以配置带参构造函数)。
(2)属性必须是private的(为了保护私有数据)。
(3)必须定义一整套的getter/setter方法(如属性名为name, 方法名就为getName/setName)。
说明:
(1)在传统的Javabean开发环境下,属性配置是通过GUI图形界面配置的,框架在生成控件对象时无法传入属性参数,所以要求bean统一提供默认无参构造函数。但在spring中,我们可以通过配置文件预先配置构造函数参数,所以可以只提供带参构造函数。
(2)属性私有和getter/setter方法的定义,使得框架能够根据属性名的配置自动生成方法名(如属性名为name, 方法名就为getName/setName),从而通过反射机制获取方法对象,进而可以实现属性的获取和设置。
用户定义bean的示例如下(也可以通过eclipse等开发环境自动生成setter/getter):
class MyPanel implements Serializable { private String name; private int width; // 默认构造函数 public MyPanel {} // setter & getter public String getName() { return name; } public void setName(String name) { this.name = name; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } }
二,bean的内省(反射机制)实现:
MyBean.java:
package com.myBean; public class MyBean { private String name; private int width; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } }
反省机制:
MyBeanImpl.java:
package com.myBean; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Field; import java.lang.Integer; import java.util.Iterator; import java.util.Map; import java.util.HashMap; import java.util.Set; public class MyBeanImpl { // Assume that these are bean configurations private static final String beanName = "com.myBean.MyBean"; private static final HashMap propertyMap = new HashMap(); static { propertyMap.put("name", "rootPanel"); propertyMap.put("width", "99"); } public static Method getSetter(Class clazz, String propertyName) { String setterName = "set" + propertyName.substring(0, 1) .toUpperCase() + propertyName.substring(1); Method[] methods = clazz.getMethods(); for (int i = 0; i < methods.length; i++) { if (methods[i].getName() .equals(setterName)) { // found setter return methods[i]; } } return null; } public static Object getFieldValue(Class clazz, String propertyName, String value) { Field[] fields = clazz.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { if (fields[i].getName() .equals(propertyName)) { // found setter if (fields[i].getType() .getSimpleName() .equals("Integer") || fields[i].getType() .getSimpleName() .equals("int")) { return Integer.valueOf(value); } else if (fields[i].getType() .getSimpleName() .equals("String")) { return value; } else return null; } } return null; } public static void main(String[] args) { Set propertySet = propertyMap.entrySet(); try { Class clazz = Class.forName(beanName); // new object by default constructor Constructor cons = clazz.getConstructor(null); Object obj = cons.newInstance(null); // configure fields Iterator iter = propertySet.iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); String propertyName = (String) entry.getKey(); String propertyValue = (String) entry.getValue(); Method setter = getSetter(clazz, propertyName); if (setter == null) { throw new Exception("find no setter of " + propertyName); } // execute setter Object[] objs = { getFieldValue(clazz, propertyName, propertyValue) }; setter.invoke(obj, objs); } System.out.println(((MyBean) obj) .getName()); System.out.println(((MyBean) obj) .getWidth()); } catch (Exception e) { e.printStackTrace(); } } }
说明:以上代码利用反射机制模拟实现Integer/int/String类型属性的setter方式。当然,代码不具备通用性(使用了if/else结构的类型判断,也没有抽象出接口和类),不过可以看出Javabean底层框架的一种实现方式。JavaBean包使用了BeanInfo接口来描述一个bean(类),每个bean(如命名为Example)对应的BeanInfo名为ExampleBeanInfo,每个BeanInfo需要用户实现getPropertyDescriptors()接口,以便GUI开发环境可以通过该接口获取该bean下的所有属性描述符数组PropertyDescriptor[]。
每个PropertyDescriptor在实现的过程中,如果是自定义类型,还需要通过PropertyDescriptor.setPropertyEditorClass()方法注册用户自定义的PropertyEditor,这样,当GUI环境在设置或者获取该自定义类型属性的时候就可以正常工作了。
JavaBean是使用Java语言开发的一个可重用组件,对于程序员来说,最好的一点就是JavaBean可以实现代码的重复利用以及对于程序的易维护性。最后大家如果想要了解更多其他工具教程知识,敬请关注奇Q工具网。
推荐阅读: