JaveBean 详解

一、JavaBean简介

        JavaBean是使用Java语言描述的软件组件模型,简单地说,它就是一个可以重复使用的Java类。JavaBean可分为可视化组件和非可视化组件,其中可视化组件包括简单的GUI元素(例如,文本框、按钮)及一些报表组件等。非可视化组件是在实际开发中经常被使用到的并且在应用程序中起着至关重要的作用。其主要功能是用来封装业务逻辑(功能实现)、数据库操作(例如,数据处理、连接数据库)等。

 

1、为什么要使用JavaBean

        在实际的开发过程中,通常会出现重复的代码或者段落,此时就会大大降低程序的可重用性并且浪费时间。使用JavaBean就可以大大简化程序的设计过程并且方便了其它程序的重复使用。 

        JavaBean在服务器端的应用具有非常强大的优势,非可视化的JavaBean可以非常好地实现控制逻辑、业务逻辑、表示层之间的分离,从而大大降低了它们之间的耦合度。非可视化的JavaBean现在多用于后台处理,这样会使系统具有一定的灵活性。 

        JavaBean是Java程序的一种,所使用的语法和其它类似的Java程序一致。在程序中使用JavaBean具有以下优点:

        (1)可以实现代码的重复利用。

        (2)易编写、易维护、易使用。

        (3)它可以压缩在jar文件中,以更小的体积在网络中应用 

        (4)完全是Java语言编写,可以在任何安装了Java运行环境的平台上的使用,而不需要重新编译。 

 

 2、JavaBean的形式和要素

        编写JavaBean就是编写一个Java的类,这个类创建的一个对象称做一个Bean。为了能让使用这个bean的应用程序构建工具(比如JSP引擎)知道这个bean的属性和方法,只需在类的方法命名上遵守以下规则:

        (1)如果类的成员变量的名字是xxx,那么为了更改或获取成员变量的值,     即更改或获取属性,在类中可以使用两个方法:

                  ●  getXXX():用来获取属性xxx。

                  ●  setXXX():用来修改属性xxx.。

        (2)对于boolean类型的成员变量,即布尔逻辑类型的属性,允许使用"is“     代替上面的"get"和"set"。

        (3)类中方法的访问属性都必须是public的。

        (4)类中如果有构造方法,那么这个构造方法也是public的并且没有参数。

JavaBean示例:

 

public class JavaBeanDemo implements Serializable { // 实现了Serializable接口
	JavaBeanDemo() {
	} // 无参的构造方法

	private int id; // 私有属性Id
	private String name; // 私有属性name

	public int getId() {
		return id;
	}

	public void setId(int id) { // set()方法
		this.id = id;
	}

	public String getName() { // get()方法
		return name;
	}

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

  

 

二、JavaBean属性

 

1、简单属性

        JavaBean的简单属性(Simple属性)表示为一般数据类型的变量并且getXXX()和setXXX()方法是以属性来命名的。例如: 

 

 

public class Hello {
	Hello() {
	} // 无参构造方法

	private String name; // 定义String类型的简单属性name
	private boolean info;

	public String getName() { // 简单属性的getXxx()方法
		return name;
	}

	public void setName(String name) { // 简单属性的setXxx()方法
		this.name = name;
	}

	public boolean isInfo() { // 布尔类型的取值方法
		return info;
	}

	public void setInfo(boolean info) { // 布尔类型的setXxx方法
		this.info = info;
	}
}

 

 

2、索引属性

        JavaBean的索引属性(Indexed属性)表示一个数组值或者一个集合,与Simple属性一样可以使用getXXX()和setXXX()方法来获取值,例如:

 

public class IndexedBean {
	
	public int[] array = new int[8];

	public int[] getArray() { // 返回整个数组
		return array;
	}

	public void setArray(int[] array) { // 为整个数组赋值
		this.array = array;
	}

	public void setArray(int index, int value) { // 为数组中的某个元素赋值
		this.array[index] = value;
	}

	public int getArray(int index) { // 返回数组中的某个值
		return array[index];
	}

}

 使用Indexed属性除了表示数组之外,还可以表示集合类。

 

 

3、束缚属性

        束缚属性(Bound)也称为关联属性,它是当该种属性的值发生变化时,要通知其它的对象。每次属性值改变时,这种属性就触发一个PropertyChange事件(在Java程序中,事件也是一个对象)。事件中封装了属性名、属性的原值、属性变化后的新值。这种事件是传递到其它的Bean,至于接收事件的Bean应做什么动作由其自己定义。包含关联属性的Bean必须具有以下的功能:  

        (1)允许事件监听器注册和注销与其有关的属性修改事件。

       (2)当修改一个关联属性时,可以在相关的监听器上触发属性修改 事件。 

        利用java.beans.PropertyChangeSupport类创建出PropertyChangeSupport类的对象,从而可以用于管理注册的监听器列表和属性修改事件通知的发送。JavaBean还需要实现addPropertyChangeLinster()方法和removePropertyChangeLinster()方法,以便添加和取消属性变化的监听器。

          下面就是束缚属性的例子:

 

 

package com.cn.fangxin.javabean;

import java.beans.*;

/**
 * javabean 束缚属性测试
 * 
 * @author Tommy
 * 
 */
public class JavaBeanBoundProperty {

	private static final long serialVersionUID = 1L;

	String ourString = "Hello"; // ourString是一个bound属性

	// 允许事件监听器注册和注销与其有关的属性修改事件;
	private PropertyChangeSupport changes = new PropertyChangeSupport(this);

	public String getOurString() {
		return ourString;
	}

	public void setOurString(String newString) {
		String oldString = ourString;
		ourString = newString;
		changes.firePropertyChange("ourString", oldString, newString);
	}

	/**
	 * JavaBean还需要实现addPropertyChangeLinster()方法和removePropertyChangeLinster()方法,以便添加和取消属性变化的监听器。
	 * @param l
	 */
	public void addPropertyChangeListener(PropertyChangeListener l) {
		changes.addPropertyChangeListener(l);
	}

	public void removePropertyChangeListener(PropertyChangeListener l) {
		changes.removePropertyChangeListener(l);
	}
	
	public static void main(String[] args) {
		
		JavaBeanBoundProperty p = new JavaBeanBoundProperty();
		//添加监听者,这里可以添加多个监听者
		p.addPropertyChangeListener(new OurStringPropertyListener());
		
		p.setOurString("设置属性新值");
		
	}

}

 

 

    监听者类:

 

package com.cn.fangxin.javabean;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

/**
 * OurString属性改变的监听者
 * @author Tommy
 *
 */
public class OurStringPropertyListener implements PropertyChangeListener {

	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		System.out.println("JavaBeanBoundProperty 的ourString 属性改变了");
		System.out.println("旧值:" + evt.getOldValue() + ",新值:" + evt.getNewValue());
	}

}

 

运行程序输出:

        JavaBeanBoundProperty 的ourString 属性改变了

        旧值:Hello,新值:设置属性新值

 

4、限制属性

        限制属性(constrained)是指当这个属性的值要发生变化时,与这个属性已建立了某种连接的其它外部Java对象可否决该属性值的改变(限制属性的监听者通过抛出PropertyVetoException来阻止该属性值的改变),Bean本身也可以否决该Bean属性值的改变。

        一个限制属性有两种监听者:属性变化监听者和取消属性改变的监听者。取消属性改变的监听者在自己的对象代码中有相应的控制语句,在监听到有限制属性要发生变化时,在控制语句中判断是否应否决这个属性值的改变。 

        利用java.beans.VetoableChangeSupport类的fireVetoableChange()方法传递属性名称、改变前的值和改变后的值等信息。JavaBean还需要实现addVetoableChangeLinster()方法和removeVetoableChangeLinster()方法,以便添加和取消属性变化的监听器。

      注意:由于限制属性使用了错误处理,编程的时候要特别注意 异常的处理方式。

 下面就是限制属性的例子:

package com.cn.fangxin.javabean;

import java.beans.*;

/**
 * javabean 束缚属性测试
 * 
 * @author Tommy
 * 
 */
public class JavaBeanBoundProperty {

	private static final long serialVersionUID = 1L;

	String ourString = "Hello"; // ourString是一个bound属性

	// 允许事件监听器注册和注销与其有关的属性修改事件;
	private PropertyChangeSupport changes = new PropertyChangeSupport(this);
	
	private VetoableChangeSupport vetos=new VetoableChangeSupport(this);

	public String getOurString() {
		return ourString;
	}

	public void setOurString(String newString) throws PropertyVetoException {
		String oldString = ourString;
		ourString = newString;
		changes.firePropertyChange("ourString", oldString, newString);
		vetos.fireVetoableChange("ourString", oldString, newString);
	}

	/**
	 * JavaBean还需要实现addPropertyChangeLinster()方法和removePropertyChangeLinster()方法,以便添加和取消属性变化的监听者。
	 * @param l
	 */
	public void addPropertyChangeListener(PropertyChangeListener l) {
		changes.addPropertyChangeListener(l);
	}

	public void removePropertyChangeListener(PropertyChangeListener l) {
		changes.removePropertyChangeListener(l);
	}
	
	/**
	 * 
	 * @param l
	 */
	public void addVetoableChangeListener(VetoableChangeListener l) {
		vetos.addVetoableChangeListener(l);
	}

	public void removeVetoableChangeListener(VetoableChangeListener l) {
		vetos.removeVetoableChangeListener(l);
	}
	
	public static void main(String[] args) throws PropertyVetoException {
		
		JavaBeanBoundProperty p = new JavaBeanBoundProperty();
		//添加监听者,这里可以添加多个监听者
		p.addPropertyChangeListener(new OurStringPropertyListener());
		
		//阻止属性改变的监听者
		p.addVetoableChangeListener(new OurStringPropertyListener());
		
		//设置为值为"test"监听者会抛出异常阻止属性改变。
		p.setOurString("test");
		System.out.println("打印属性值:" + p.getOurString());
		
	}

}

 

 监听者类:

package com.cn.fangxin.javabean;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;

/**
 * OurString属性改变的监听者
 * @author Tommy
 *
 */
public class OurStringPropertyListener implements PropertyChangeListener,VetoableChangeListener {

	@Override
	public void propertyChange(PropertyChangeEvent evt) {
//		System.out.println("JavaBeanBoundProperty 的ourString 属性改变了");
//		System.out.println("旧值:" + evt.getOldValue() + ",新值:" + evt.getNewValue());
	}

	@Override
	public void vetoableChange(PropertyChangeEvent evt)
			throws PropertyVetoException {
		String newVal = (String) evt.getNewValue();
		if ("test".equals(newVal)) {
			throw new PropertyVetoException("设置的新值为test,所以阻止属性改变", evt);
		}
	}

}

 

 运行结果:Exception in thread "main" java.beans.PropertyVetoException: 设置的值为test,所以阻止属性改变

 

三、JavaBean的作用域 

 

1、page作用域

        page作用域在这4种类型中范围是最小的,客户端每次请求访问时都会创建一个JavaBean对象。JavaBean对象的有效范围是客户请求访问的当前页面文件,当客户执行当前的页面文件完毕后JavaBean对象结束生命。

        在page范围内,每次访问页面文件时都会生成新的JavaBean对象,原有的JavaBean对象已经结束生命期。 

2、request作用域 

        当scope为request时,JavaBean对象被创建后,它将存在于整个request的生命周期内,request对象是一个内建对象,使用它的getParameter方法可以获取表单中的数据信息。

       Request范围的JavaBean与request对象有着很大的关系,它的存取范围除了page外,还包括使用动作元素<jsp:include>和<jsp:forward>包含的网页,所有通过这两个操作指令连接在一起的JSP程序都可以共享同一个JavaBean对象。 

3、session作用域

        当scope为session时,JavaBean对象被创建后,它将存在于整个session的生命周期内,session对象是一个内建对象,当用户使用浏览器访问某个网页时,就创建了一个代表该链接的session对象,同一个session中的文件共享这个JavaBean对象。客户对应的session生命期结束时JavaBean对象的生命也结束了。在同一个浏览器内,JavaBean对象就存在于一个session中。当重新打开新的浏览器时,就会开始一个新的session。每个session中拥有各自的JavaBean对象。

4、application作用域 

        当scope为application时,JavaBean对象被创建后,它将存在于整个主机或虚拟主机的生命周期内,application范围是JavaBean的生命周期最长的。同一个主机或虚拟主机中的所有文件共享这个JavaBean对象。如果服务器不重新启动,scope为application的JavaBean对象会一直存放在内存中,随时处理客户的请求,直到服务器关闭,它在内存中占用的资源才会被释放。在此期间,服务器并不会创建新的JavaBean组件,而是创建源对象的一个同步拷贝,任何拷贝对象发生改变都会使源对象随之改变,不过这个改变不会影响其它已经存在的拷贝对象。

通过下面的实例说明4个作用域:

首先,创建一个JavaBean:“Scope.java” 。

package com.cn.fangxin.javabean;

public class Scope {
	
	public Scope(){}                                        //无参的构造函数  
    private int number=0;                                //初始化变量number的值为0  
    public int getNmuber(){                             //增加并返回变量number的值  
        number++;  
        return number;  
         }  
    public void setNumber(int newNumber) {    
        this.number = newNumber;       //给变量number赋新值  
    }  

}

 然后,创建名称为“scope.jsp”的页面文件,用来显示JavaBean存在的范围的具体区别。主要代码:

 

<body>
		<jsp:useBean id="pageScope" scope="page" class="com.cn.fangxin.javabean.Scope" />
		<% out.println("使用page获取的数据为:" + pageScope.getNmuber());%>

		<jsp:useBean id="requestScope" scope="request" class="com.cn.fangxin.javabean.Scope" />
		<%out.println("使用request获取的数据为:" + requestScope.getNmuber());%>

		<jsp:useBean id="sessionScope" scope="session" class="com.cn.fangxin.javabean.Scope" />
		<% out.println("使用session获取的数据为:" + sessionScope.getNmuber()); %>

		<jsp:useBean id="applicationScope" scope="application"
			class="com.cn.fangxin.javabean.Scope" />
		<% out.println("使用application获取的数据为:" +
                                  applicationScope.getNmuber());%>
	</body>

程序运行结果如图1所示(刷新8次的结果): 

 

关闭该浏览器,重新打开新的浏览器后的结果如图2所示: 



 

 

猜你喜欢

转载自tommy-lu.iteye.com/blog/2228716