什么是JavaBean
JavaBean就是一个符合一定规则的java类。JavaBean要含有一个公共的且无参数的构造器,内部通过getter/setter方法暴露对JavaBean字段值的操作。为了使 JavaBean 的属性名和存取方法都符合规范, Sun 在 JSR 文档中规定了属性名和存取方法。
属性名的映射规则:
属性名对应的存取方法为 get/set加上首字母大写的属性名,如属性 userName 的存取方法为 setUserName/getUserName。这样属性名和存取方法都符合命名规范。这个规则强制的,如果不符合规则就会出现异常。
一些特殊情况:
- 1、如果属性名的第二个字母大写,那么该属性名直接用作 getter/setter 方法中get/set的后部分,就是说大小写不变。例如属性名为uName,方法是getuName/setuName。
- 2、如果前两个字母是大写(一般的专有名词和缩略词都会大写),也是属性名直接用作 getter/setter方法中get/set 的后部分。例如属性名为URL,方法是getURL/setURL。 JavaBean 属性命名不要以is开头,如果正常属性命名eclipse生成如下:
private boolean name;
public boolean isName() {
return name;
}
public void setName(boolean name) {
this.name = name;
}
如果是is开头:
private boolean isName;
public boolean isName() {
return isName;
}
public void setName(boolean isName) {
this.isName = isName;
}
这样就会当name属性去处理,可能会导致一些框架的报错。
Introspector(内省)
Introspector(内省)是java提供的一套操作JavaBean属性、事件和方法的知识。Introspector将分别分析bean的类和超类,寻找显式或隐式信息,使用这些信息构建一个全面描述目标 bean 的BeanInfo对象。
对于每个"Foo"类,如果存在相应的"FooBeanInfo"类,显式信息可能是可用的,查询这些信息时,FooBeanInfo类会提供一个非null值。通过获得目标bean类的完全受限定包名称并追加"BeanInfo"形成一个新类,首先查找BeanInfo类。如果此操作失败,则采用此名称的最终类名称组件,在BeanInfo包搜索路径中指定的每个包中搜索该类。因此对于某个类,比如说"sun.xyz.OurButton",首先需要查找称为"sun.xyz.OurButtonBeanInfo"的BeanInfo类,如果失败,则查找BeanInfo搜索路径中的每个包来搜索OurButtonBeanInfo类。对于默认搜索路径,这意味着将查找"sun.beans.infos.OurButtonBeanInfo"。如果某个类提供有关其自身的显式BeanInfo,则将它添加到从分析所有派生类得到的BeanInfo信息中,并将显式信息视为当前类及其基类的确定的信息,无需进一步深入超类链进行分析。如果没有在某个类上发现显式BeanInfo,则使用低层次的反射来研究类的方法,并应用标准设计模式来标识属性存储器、事件源或公共方法。然后深入分析类的超类,从它那里(可能在超类链的顶部)添加信息。因为 Introspector 缓存BeanInfo类来获得更好的性能,所以如果在使用多个类加载器的应用程序中使用它,则需小心谨慎。通常,在破坏一个已用于introspect类的ClassLoader时,应使用 Introspector.flushCaches或Introspector.flushFromCaches 方法从缓存中清除所有内省的类。
方法介绍:
1.获得一个字符串并将它转换成普通 Java 变量名称大写形式的实用工具方法。这通常意味着将首字符从大写转换成小写,但在(不平常的)特殊情况下,当有多个字符且第一个和第二个字符都是大写字符时,不执行任何操作。因此 "FooBah" 变成 "fooBah","X" 变成 "x",但 "URL" 仍然是 "URL"。 方法返回值 | 方法参数 ---|--- static String | decapitalize(String name) 参数:
name - 要取消大写化的字符串。
返回:
取消大写化的字符串。
例子:
public static void main(String[] args) {
System.out.println(testDecapitalize("FooBah"));
System.out.println(testDecapitalize("X"));
System.out.println(testDecapitalize("URL"));
}
public static String testDecapitalize(String name){
return Introspector.decapitalize(name);
}
输出:
fooBah
x
URL
2.获得将用来查找 BeanInfo 类的包名称的列表。 返回: 为了查找 BeanInfo 类而被搜索的包名称数组。此数组的默认值与实现有关,例如 Sun 实现最初设置为 {"sun.beans.infos"}。 方法返回值 | 方法参数 ---|--- static String[] | getBeanInfoSearchPath() 例子:
public static void testGetBeanInfoSearchPath(){
String[] infoSearchPath = Introspector.getBeanInfoSearchPath();
for(String path : infoSearchPath){
System.out.println(path);
}
}
输出:
sun.beans.infos
3.更改将用来查找 BeanInfo 类的包名称的列表。 方法返回值 | 方法参数 ---|--- static void | setBeanInfoSearchPath(String[] path) 4.刷新所有 Introspector 的内部缓存。 方法返回值 | 方法参数 ---|--- static void | flushCaches() 5.刷新给定类的 Introspector 的内部缓存信息。 方法返回值 | 方法参数 ---|--- static void | flushFromCaches(Class<?> clz) 6.在 Java Bean上进行内省,了解其所有属性、公开的方法和事件(包括从子类中继承过来的属性,公开方法和事件)。如果 Java Bean 的 BeanInfo 类以前已经被内省,则从 BeanInfo 缓存中检索 BeanInfo 类。 方法返回值 | 方法参数 ---|--- static BeanInfo | getBeanInfo(Class<?> beanClass) 7.在给定的“断”点之下,在 Java Bean 上进行内省,了解其所有属性和公开的方法。stopClass 或其基类中的所有方法/属性/事件都将在分析中被忽略。 方法返回值 | 方法参数 ---|--- static BeanInfo | getBeanInfo(Class<?>beanClass,Class<?> stopClass) 8.在 Java Bean上进行内省,了解其所有属性、公开的方法和事件,并将结果用一些控制标记表示。 方法返回值 | 方法参数 ---|--- static BeanInfo |getBeanInfo(Class<?> beanClass, int flags)
getBeanInfo例子:
public static void testGetBeanInfo() {
try {
BeanInfo userInfo = Introspector.getBeanInfo(User.class);
PropertyDescriptor[] propertyDescriptors = userInfo.getPropertyDescriptors();
System.out.println("getBeanInfo (User.class)..............");
pringProName(propertyDescriptors);
BeanInfo userInfo1 = Introspector.getBeanInfo(User.class,Object.class);
PropertyDescriptor[] propertyDescriptors1 = userInfo1.getPropertyDescriptors();
System.out.println("getBeanInfo1 (User.class ~ Object.class).............");
pringProName(propertyDescriptors1);
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
private static void pringProName(PropertyDescriptor[] propertyDescriptors) {
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
String name = propertyDescriptor.getDisplayName();
System.out.println(name);
}
}
输出:
getBeanInfo (User.class)..............
age
class
name
weight
getBeanInfo1 (User.class ~ Object.class).............
age
name
weight
9.MethodDescriptor 描述了一种特殊方法,即 Java Bean 支持从其他组件对其进行外部访问。 方法返回值 | 方法参数 ---|--- MethodDescriptor[] |getMethodDescriptors() 10.获得 beans PropertyDescriptor。 方法返回值 | 方法参数 ---|--- PropertyDescriptor[] |getPropertyDescriptors() 11.Method相关方法: Method getReadMethod()获得应该用于读取属性值的方法。 Method getWriteMethod()获得应该用于写入属性值的方法。 void setReadMethod(MethodreadMethod)设置应该用于读取属性值的方法。 void setWriteMethod(Method writeMethod) 设置应该用于写入属性值的方法。 例子:
public static void tetsPropertyDescriptorMethod(){
User user = new User();
user.setName("test");
try {
BeanInfo userInfo = Introspector.getBeanInfo(User.class);
PropertyDescriptor[] propertyDescriptors = userInfo.getPropertyDescriptors();
System.out.println("PropertyDescriptorMethod (User.class)..............");
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
if("name".equals(propertyDescriptor.getName())){
Method readMethod = propertyDescriptor.getReadMethod();
Object invoke = readMethod.invoke(user);
System.out.println(invoke);
Method writeMethod = propertyDescriptor.getWriteMethod();
writeMethod.invoke(user, "testName");
System.out.println(user);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
PropertyDescriptorMethod (User.class)..............
test
User [name=testName, age=0]