javaBean是如何工作的?简述javaBean的工作过程

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工具网。

推荐阅读:

java测试工程师是干什么的?应具备哪些职业素质?

fastjson如何使用?fastjson使用方法

javabean的作用域从小到大是什么?javabean如何理解?