关于Bean

什么是Bean?

一个Bean 就是一个类。我们不必为制造任何的Bean而编写一些特殊的代码或者使用特殊的编程语言。事实上,我们唯一需要做的是略微地修改我们对我们方法命名的办法。方法名通知应用程序构建工具是否是一个属性,一个事件或是一个普通的方法。

在Java 的文件中,命名规则被错误地曲解为“设计范式”。这十分的不幸,因为设计范式惹来不少的麻烦。命名规则不是设计范式,它是相当的简单:

(1) 因为属性被命名为xxx,我们代表性的创建两个方法:getXxx()和setXxx()。注意get 或set 后的第一个字母大写以产生属性名。“get”和“set”方法产生同样类型的自变量。“set”和“get”的属性名和类型名之间没有关系。

(2) 对于布尔逻辑型属性,我们可以使用上面的“get”和“set”方法,但我们也可以用“is”代替“ get”。

(3) Bean 的普通方法不适合上面的命名规则,但它们是公用的。

(4) 对于事件,我们使用“listener(接收器)”方法。这种方法完全同我们看到过的方法相同:

(addFooBarListener(FooBarListener)和removeFooBarListener(FooBarListener)方法用来处理FooBar 事件。大多数时候内建的事件和接收器会满足我们的需要,但我们可以创建自己的事件和接收器接口。

上面的第一点回答了一个关于我们可能注意到的从Java 1.0 到Java 1.1 的改变的问题:一些方法的名字太过于短小,显然改写名字毫无意义。现在我们可以看到为了制造Bean 中的特殊的组件,大多数的这些修改不得不适合于“get”和“set”命名规则。

Bean代码示例:

 1 //: Frog.java
 2 // A trivial Java Bean
 3 package frogbean;
 4 import java.awt.*;
 5 import java.awt.event.*;
 6 class Spots {}
 7 public class Frog {
 8 private int jumps;
 9 private Color color;
10 private Spots spots;
11 private boolean jmpr;
12 public int getJumps() { return jumps; }
13 public void setJumps(int newJumps) {
14 jumps = newJumps;
15 }
16 public Color getColor() { return color; }
17 public void setColor(Color newColor) {
18 color = newColor;
19 }
20 public Spots getSpots() { return spots; }
21 public void setSpots(Spots newSpots) {
22 spots = newSpots;
23 }
24 public boolean isJumper() { return jmpr; }
25 public void setJumper(boolean j) { jmpr = j; }
26 public void addActionListener(
27 ActionListener l) {
28 //...
29 }
30 public void removeActionListener(
31 ActionListener l) {
32 // ...
33 }
34 public void addKeyListener(KeyListener l) {
35 // ...
36 }
37 public void removeKeyListener(KeyListener l) {
38 // ...
39 }
40 // An "ordinary" public method:
41 public void croak() {
42 System.out.println("Ribbet!");
43 }
44 } //

首先,我们可看到Bean 就是一个类。通常,所有我们的字段会被作为专用,并且可以接近的唯一办法是通过方法。紧接着的是命名规则,属性是jump,color,jumper,spots(注意这些修改是在第一个字母在属性名的情况下进行的)。虽然内部确定的名字同最早的三个例子的属性名一样,在jumper 中我们可以看到属性名不会强迫我们使用任何特殊的内部可变的名字(或者,真的拥有一些内部的可变的属性名)。Bean 事件的句柄是ActionEvent 和KeyEvent ,这是根据有关接收器的“add”和“remove”命名方法得出的。最后我们可以注意到普通的方法croak()一直是Bean 的一部分,仅仅是因为它是一个公共的方法,而不是因为它符合一些命名规则。

用I n t r o s p e c t o r 提取B e a n I n f o

  1 //: BeanDumper.java
  2
  3 // A method to introspect a Bean
  4
  5 import java.beans.*;
  6
  7 import java.lang.reflect.*;
  8
  9 public class BeanDumper {
 10
 11 public static void dump(Class bean){
 12
 13 BeanInfo bi = null;
 14
 15 try {
 16
 17 bi = Introspector.getBeanInfo(
 18
 19 bean, java.lang.Object.class);
 20
 21 } catch(IntrospectionException ex) {
 22
 23 System.out.println("Couldn‘t introspect " +
 24
 25 bean.getName());
 26
 27 System.exit(1);
 28
 29 }
 30
 31 PropertyDescriptor[] properties =
 32
 33 bi.getPropertyDescriptors();
 34
 35 for(int i = 0; i < properties.length; i++) {
 36
 37 Class p = properties[i].getPropertyType();
 38
 39 System.out.println(
 40
 41 "Property type:\n " + p.getName());
 42
 43 System.out.println(
 44
 45 "Property name:\n " +
 46
 47 properties[i].getName());
 48
 49 Method readMethod =
 50
 51 properties[i].getReadMethod();
 52
 53 if(readMethod != null)
 54
 55 System.out.println(
 56
 57 "Read method:\n " +
 58
 59 readMethod.toString());
 60
 61 Method writeMethod =
 62
 63 properties[i].getWriteMethod();
 64
 65 if(writeMethod != null)
 66
 67 System.out.println(
 68
 69 "Write method:\n " +
 70
 71 writeMethod.toString());
 72
 73 System.out.println("====================");
 74
 75 }
 76
 77 System. out.println("Public methods:");
 78
 79 MethodDescriptor[] methods =
 80
 81 bi.getMethodDescriptors();
 82
 83 for(int i = 0; i < methods.length; i++)
 84
 85 System.out.println(
 86
 87 methods[i].getMethod().toString());
 88
 89 System.out.println("======================");
 90
 91 System.out.println("Event support:");
 92
 93 EventSetDescriptor[] events =
 94
 95 bi.getEventSetDescriptors();
 96
 97 for(int i = 0; i < events.length; i++) {
 98
 99 System.out.println("Listener type:\n " +
100
101 events[i].getListenerType().getName());
102
103 Method[] lm =
104
105 events[i].getListenerMethods();
106
107 for(int j = 0; j < lm.length; j++)
108
109 System.out.println(
110
111 "Listener method:\n " +
112
113 lm[j].getName());
114
115 MethodDescriptor[] lmd =
116
117 events[i].getListenerMethodDescriptors();
118
119 for(int j = 0; j < lmd.length; j++)
120
121 System.out.println(
122
123 "Method descriptor:\n " +
124
125 lmd[j].getMethod().toString());
126
127 Method addListener =
128
129 events[i].getAddListenerMethod();
130
131 System.out.println(
132
133 "Add Listener Method:\n " +
134
135 addListener.toString());
136
137 Method removeListener =
138
139 events[i].getRemoveListenerMethod();
140
141 System.out.println(
142
143 "Remove Listener Method:\n " +
144
145 removeListener.toString());
146
147 System.out.println("====================");
148
149 }
150
151 }
152
153 // Dump the class of your choice:
154
155 public static void main(String[] args) {
156
157 if(args.length < 1) {
158
159 System.err.println("usage: \n" +
160
161 "BeanDumper fully.qualified.class");
162
163 System.exit(0);
164
165 }
166
167 Class c = null;
168
169 try {
170
171 c = Class.forName(args[0]);
172
173 } catch(ClassNotFoundException ex) {
174
175 System.err.println(
176
177 "Couldn‘t find " + args[0]);
178
179 System.exit(0);
180
181 }
182
183 dump(c);
184
185 }
186
187 } ///:

  

BeanDumper.dump()是一个可以做任何工作的方法。首先它试图创建一个BeanInfo 对象,如果成功地调用BeanInfo 的方法,就产生关于属性、方法和事件的信息。在Introspector.getBeanInfo()中,我们会注意到有一个另外的自变量。由它来通知Introspector 访问继承体系的地点。在这种情况下,它在分析所有对象方法前停下,因为我们对看到那些并不感兴趣。因为属性,getPropertyDescriptors()返回一组的属性描述符号。对于每个描述符号我们可以调用getPropertyType()方法彻底的通过属性方法发现类的对象。这时,我们可以用getName()方法得到每个属性的假名(从方法名中提取),getname()方法用getReadMethod()和getWriteMethod()完成读和写的操作。最后的两个方法返回一个可以真正地用来调用在对象上调用相应的方法方法对象(这是映象的一部分)。对于公共方法getMethodDescriptors( )返回一组方法描述字符。每一个我们都可以得到相当的方法对象并可以显示出它们的名字。对于事件而言,getEventSetDescriptors()返回一组事件描述字符。它们中的每一个都可以被查询以找出接

收器的类,接收器类的方法以及增加和删除接收器的方法。BeanDumper 程序打印出所有的这些信息。

如果我们调用BeanDumper 在Frog 类中,就像这样:

java BeanDumper frogbean.Frog

它的输出结果如下(已删除这儿不需要的额外细节):

  1 class name: Frog
  2
  3 Property type:
  4
  5 Color
  6
  7 Property name:
  8
  9 color
 10
 11 Read method:
 12
 13 public Color getColor()
 14
 15 Write method:
 16
 17 public void setColor(Color)
 18
 19 ====================
 20
 21 Property type:
 22
 23 Spots
 24
 25 Property name:
 26
 27 spots
 28
 29 Read method:
 30
 31 public Spots getSpots()
 32
 33 Write method:
 34
 35 public void setSpots(Spots)
 36
 37 ====================
 38
 39 Property type:
 40
 41 boolean
 42
 43 Property name:
 44
 45 jumper
 46
 47 Read method:
 48
 49 public boolean isJumper()
 50
 51 Write method:
 52
 53 public void setJumper(boolean)
 54
 55 ====================
 56
 57 Property type:
 58
 59 int
 60
 61 Property name:
 62
 63 jumps
 64
 65 Read method:
 66
 67 public int getJumps()
 68
 69 Write method:
 70
 71 public void setJumps(int)
 72
 73 ====================
 74
 75 Public methods:
 76
 77 public void setJumps(int)
 78
 79 public void croak()
 80
 81 public void removeActionListener(ActionListener)
 82
 83 public void addActionListener(ActionListener)
 84
 85 public int getJumps()
 86
 87 public void setColor(Color)
 88
 89 public void setSpots(Spots)
 90
 91 public void setJumper(boolean)
 92
 93 public boolean isJumper()
 94
 95 public void addKeyListener(KeyListener)
 96
 97 public Color getColor()
 98
 99 public void removeKeyListener(KeyListener)
100
101 public Spots getSpots()
102
103 ======================
104
105 Event support:
106
107 Listener type:
108
109 KeyListener
110
111 Listener method:
112
113 keyTyped
114
115 Listener method:
116
117 keyPressed
118
119 Listener method:
120
121 keyReleased
122
123 Method descriptor:
124
125 public void keyTyped(KeyEvent)
126
127 Method descriptor:
128
129 public void keyPressed(KeyEvent)
130
131 Method descriptor:
132
133 public void keyReleased(KeyEvent)
134
135 Add Listener Method:
136
137 public void addKeyListener(KeyListener)
138
139 Remove Listener Method:
140
141 public void removeKeyListener(KeyListener)
142
143 ====================
144
145 Listener type:
146
147 ActionListener
148
149 Listener method:
150
151 actionPerformed
152
153 Method descriptor:
154
155 public void actionPerformed(ActionEvent)
156
157 Add Listener Method:
158
159 public void addActionListener(ActionListener)
160
161 Remove Listener Method:
162
163 public void removeActionListener(ActionListener)
164
165 ====================

这个结果揭示出了Introspector 在从我们的Bean 产生一个BeanInfo 对象时看到的大部分内容。我们可注意到属性的类型和它们的名字是相互独立的。请注意小写的属性名。(当属性名开头在一行中有超过不止的大写字母,这一次程序就不会被执行。)并且请记住我们在这里所见到的方法名(例如读和与方法)真正地从一个可以被用来在对象中调用相关方法的方法对象中产生。通用方法列表包含了不相关的事件或者属性,例如croak()。列表中所有的方法都是我们可以有计划的为Bean 调用,并且应用程序构建工具可以选择列出所有的方法,当我们调用方法时,减轻我们的任务。最后,我们可以看到事件在接收器中完全地分析研究它的方法、增加和减少接收器的方法。基本上,一旦我们拥有BeanInfo ,我们就可以找出对Bean 来说任何重要的事物。我们同样可以为Bean 调用方法,即使我们除了对象外没有任何其它的信息(此外,这也是映象的特点)。

参考书:《Java编程思想第四版》

时间: 2024-10-12 19:10:17

关于Bean的相关文章

[email&#160;protected] 和 @Bean

参考:http://wiki.jikexueyuan.com/project/spring/java-based-configuration.html @Configuration 和 @Bean 注解 带有 @Configuration 的注解类表示这个类可以使用 Spring IoC 容器作为 bean 定义的来源.@Bean 注解告诉 Spring,一个带有 @Bean 的注解方法将返回一个对象,该对象应该被注册为在 Spring 应用程序上下文中的 bean.最简单可行的 @Config

spring和hibernate整合时报sessionFactory无法获取默认Bean Validation factory

Hibernate 3.6以上版本在用junit测试时会提示错误: Unable to get the default Bean Validation factory spring和hibernate整合时报sessionFactory无法获取默认Bean Validation factory  ,是因为新版hibernate用到新的jar包造成的,默认会自动找验证包,吴国不需要这一步,可以在spring整合hibernate的配置节点中添加如下标红属性: <bean id="sessio

spring+mybati java config配置引起的bean相互引用日志报警告问题

摘要: Error creating bean with name 'XXX': Requested bean is currently in creation: Is there an unresolvable circular reference?; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: 如果把MapperScan单独配置,就不会有警告 报循环引用警告的配

spring源码阅读之Bean的加载(二)

在正式分析源码之前,先来了解一下SpringBeans里面最核心的两个类  DefaultListableBeanFactory XMLBean继承自 DefaultListableBeanFactory,而 DefaultListableBeanFactory是整个Bean加载的核心部分,是Sprin注册及加载Bean的默认实现,而对于XmlBeanFactory与 DefaultListableBeanFactory不同的地方其实就是在XmlBeanFactory中使用了自定义的XML读取器

spring源码阅读之Bean的加载(一)

Bean的概念 Bean应该是Spring里面最核心的东西了,我觉得Bean这个名字起的还是很形象的,Bean 豆:豆形种子 Spring应该就是包括在豌豆最外层的那层衣服了,而Bean就是里面的一颗一颗的豆子.我们平常开发中就是把Spring里面塞入一颗一颗的豆子.根据面向对象的开发原则,Bean其实也就是个对象,来看一看我们一个正常的系统中都配置了什么Bean: 按照面向对象的说法,我们在容器里面放入了如图所示的对象,当然这个对象可以是一个类,一个文件,一个管理器,一个接口,甚至是一个Jav

Spring @Service生成bean名称的规则

今天碰到一个问题,写了一个@Service的bean,类名大致为:BKYInfoServcie.java dubbo export服务的配置: <dubbo:service interface="com.xxx.XxxService" ref="bKYInfoServcie" /> 结果启动报错:找不到名为bKYInfoServcie的bean bean的名字不是我预期的"bKYInfoServcie",临时将bean的名字指定成了b

spring bean初始化和销毁

当实例化一个bean时,可能需要执行一些初始化操作来确保该bean处于可用状态.当不在需要bean的时候,将其从容器中移除时候,我们可能会执行一些清理的工作. 1.spring提供了:InitializingBean和DisposableBean接口 Spring容器以特殊的方式对待实现这两个接口的bean,容许他们进入bean的生命周期. 看下例子: public class TestSpring implements InitializingBean,DisposableBean { //初

Spring Custom Bean with BeanPostProcessor

Spring Custom Bean 1.BeanPostProcessors 这个接口是在spring容器初始化完bean之后 才会被调用,这个接口针对是一个容器,不能夸容器操作的,这个只能在初始化bean之后再改变一些自己的内容,如果想改变bean的结构,需要另外的一个接口:BeanFactoryPostProcessor

【spring教程之四】spring中bean的作用域

1. <bean id="stage" class="com.test.pro.Stage"> 在spring中,bean默认都是单例的,也就是说,spring容易只会实例化一次,在以后的每次调用中,都会使用同一个实例.下面的例子可以说明: 2.测试类 package com.test.pro; import org.springframework.context.ApplicationContext; import org.springframewor

3、Spring4之Bean 配置的细节

1). 若字面值中包含特殊字符,则可以使用 value 节点的 <![CDATA[]]> 把字面值包裹起来. <constructor-arg> <!-- 若 value 属性值中包含特殊字符串, 则可以使用 value 子节点来注入属性值. value 子节点中可以使用 CDATA --> <value><![CDATA[Zheng <><> zhou]]></value> </constructor-