JavaBean

JavaBean 定义

在 Java 中,有很多class的定义都符合这样的规范:

  • 若干private实例字段;
  • 通过public方法来读写实例字段。
1
2
3
4
5
6
7
8
9
10
public class Person {
private String name;
private int age;

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

public int getAge() { return this.age; }
public void setAge(int age) { this.age = age; }
}

如果读写方法符合以下这种命名规范:

1
2
3
4
// 读方法:
public Type getXyz()
// 写方法:
public void setXyz(Type value)

那么这种class被称为JavaBean

JavaBean 是一种 Java 语言写成的可重用组件。为写成 JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性。众所周知,属性名称符合这种模式,其他 Java 类可以通过自身机制发现和操作这些 JavaBean 的属性。

JavaBean 更多的是一种规范,即包含一组 set 和 get 方法的 Java 对象。JavaBean 主要用来传递数据,即把一组数据组合成一个 JavaBean 便于传输。

枚举 JavaBean 属性

内省(Introspector) 是 Java 语言对 JavaBean 类属性、事件的一种缺省处理方法。

调用 Introspector.getBeanInfo() 方法,得到的 BeanInfo 对象封装了把这个类当做 JavaBean 看的结果信息,即属性的信息。调用 BeanInfogetPropertyDescriptors(),可以获得属性的描述,可以采用遍历 BeanInfo 的方法,来查找、设置类的属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class IntrospectorTest {
public static void main(String[] args) throws Exception {
Person person = new Person();
BeanInfo info = Introspector.getBeanInfo(Person.class);
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
if (pd.getName().equals("name")){
Method methodSetName = pd.getWriteMethod();
methodSetName.invoke(person, "Freya");
Method methodGetName = pd.getReadMethod();
System.out.println(methodGetName.invoke(person, null));
}
}
}

static class Person {
private String name;
private int age;

public String getName() {
return name;
}

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

public int getAge() {
return age;
}

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

内省操作非常的繁琐,所以 Apache 开发了一套简单、易用的API来操作 Bean 的属性——BeanUtils工具包

注意:应用的时候还需要一个 logging包

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>

使用 BeanUtils 示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) throws Exception {
Person person = new Person();
BeanUtils.setProperty(person, "name", "Freya");
BeanUtils.setProperty(person, "age", 17);
BeanUtils.setProperty(person, "id", 1011);
System.out.println(BeanUtils.getProperty(person, "name"));
System.out.println("get name type:" + BeanUtils.getProperty(person, "name").getClass().getName());
System.out.println(BeanUtils.getProperty(person, "age"));
System.out.println("get age type:" + BeanUtils.getProperty(person, "age").getClass().getName()); // get age type:java.lang.String
System.out.println("get age type:" + PropertyUtils.getProperty(person, "age").getClass().getName()); // get age type:java.lang.Integer

}

设置属性的值,例如,BeanUtils.setProperty(person, “age”, 8),参数是字符串或基本类型自动包装。设置属性的值是字符串,获得的值也是字符串,不是基本类型。

PropertyUtils 类和 BeanUtils 不同在于,运行 getProperty、setProperty 操作时,没有类型转换,使用属性的原有类型或者包装类。

VO、DTO、POJO、DTO、BO的区别

VO

value object值对象,主要体现在视图的对象,对于一个WEB页面将整个页面的属性封装成一个对象。然后用一个 VO 对象在控制层与视图层进行传输交换。

DTO

Data Transfer Object 数据传输对象,经过处理后的PO,可能增加或者减少PO的属性。主要用于远程调用等需要大量传输对象的地方。比如我们一张表有100个字段,那么对应的 PO 就有100个属性。但是我们界面上只要显示10个字段,客户端用WEB service来获取数据,没有必要把整个PO对象传递到客户端,这时我们就可以用只有这10个属性的DTO来传递结果到客户端,这样也不会暴露服务端表结构.到达客户端以后,如果用这个对象来对应界面显示,那此时它的身份就转为VO。

POJO

Plain Ordinary Java Object,是一个简单的普通的Java对象。简单 Java 对象是一种概念或者接口,身份及作用随环境变化而变化。POJO 有一些private的参数作为对象的属性。然后针对每个参数定义了get和set方法作为访问的接口。它不包含业务逻辑或持久逻辑等,但不是JavaBean、EntityBean等,不具有任何特殊角色和不继承或不实现任何其它Java框架的类或接口。POJO对象有时也被称为Data对象,大量应用于表现现实中的对象。
一个POJO持久化以后就是PO。直接用它传递、传递过程中就是DTO。直接用来对应表示层就是VO。

DAO

PO持久化到数据库是要进行相关的数据库操作的(CRUQ),这些对数据库操作的方法会统一放到一个 Java 对象中,这就是DAO。

BO

POJO在业务层的体现,对于业务操作来说,更多的是从业务上来包装对象,如一个User的BO,可能包括name, age, sex, privilege, group等,这些属性在数据库中可能会在多张表中,因为每一张表对应一个PO,而我们的BO需要这些PO组合起来(或说重新拼装)才能成为业务上的一个完整对象。

联系

POJO仅包含最简单的字段属性,没有多余的东西,它本质上就是一个普通的 JavaBean。但是在POJO的基础上,能够扩展出不同的对象。

  1. 为 POJO 增加了持久化的方法(Insert、Update、Delete……)之后,POJO 就变成了 PO。
  2. 为 POJO 增加了数据绑定功能之后,POJO 就变成了 View Object,即UI Model。
  3. 为 POJO 增加业务逻辑的方法(比如单据审核、转帐……)之后,POJO就变成了Domain Model。
  4. POJO 还可以当作 DTO 使用。