内省

内省(IntroSpector)是Java语言对JavaBean类的属性、事件及方法的处理。JavaBean主要用于传递数据信息,通常被称为“值对象”(Value Object)或“VO”。JavaBean内部的方法要按照某种规则命名,例如void setName(String name)String getName()。也可以作为普通类进行操作。

  • 获取属性名的规则:如果属性名的第二个字母是小写,则把第一个字母小写。例如,getage—>age,setName—>name,getINFO—>INFO。
  • 属性名称:是通过get和set方法推断出来的,即去掉get、set后的字母,例如:getName(),setName(String name),即属性为name,而不是成员变量,因为成员变量是可见的。

内省访问JavaBean有两种方法

1 通过PropertyDescriptor来操作Bean对象

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Person person = new Person();
PropertyDescriptor pd = new PropertyDescriptor("name", Person.class);
//获得用于写入属性值的方法
Method writeMethod = pd.getWriteMethod();
writeMethod.invoke(person, "binbena");
//获得用于读取属性值的方法
Method readMethod = pd.getReadMethod();
Object nameVal = readMethod.invoke(person);
//getPropertyType(),获得属性的Class对象
System.out.printf("person name: %s,type: %s \n", nameVal, pd.getPropertyType());

2通过Introspector来操作Bean对象

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Person person = new Person();
BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd: propertyDescriptors){
    if ("name".equals(pd.getName())){
        Method writeMethod = pd.getWriteMethod();
        writeMethod.invoke(person, "binbena");
        Method readMethod = pd.getReadMethod();
        Object nameVal = readMethod.invoke(person);

        System.out.printf("person name: %s,type: %s \n", nameVal, pd.getPropertyType());
        break;
    }
}

Person.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
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;
    }
}

注解Annotation

1 元注解

对注解类的注解,可以理解为注解类的属性

  • Rentention

RententionPolicy枚举类型值,分别为:SOURCE、CLASS、RUNTIME

  • Target

ElementType枚举类型值,表示注解使用的位置,例如,@Target({ElementType.METHOD,ElementType.TYPE})

2 注解的定义

基本属性定义:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Target({ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {
    /**
     * 名称/描述
     * @return
     */
    String value() default "";

    /**
     * 当前操作
     * @return
     */
    String operate() default "";

    /**
     * 所属模块
     * @return
     */
    String module() default "";
}

数组、枚举、注解等属性定义:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
public @interface AnotationDemo{
    int[] arr() default {3,7,5};
    LoginType loginType() default LoginType.Password;
    OperationLog annotationAttr() default @OperationLog("xxx");


    enum LoginType{
        Password, Mobile;
    }

    @interface OperationLog{
        String value() default "";
    }
}

3 注解使用

1
2
3
4
5
//基本属性定义
@OperationLog(value="XXX", operate="create")

//数组、枚举、注解等属性定义
@AnotationDemo(arr = {1,3}, loginType=LoginType.Mobile, annotationAttr=@OperationLog("xxx"))

4 注解属性值获取

1
2
3
4
5
6
7
8
if(AnnotationDemo.class.isAnnotationPresent(OperationLog.class)){
	OperationLog annotation = (OperationLog)AnnotationDemo.class
    .getAnnotation(OperationLog.class);
		System.out.println(annotation.value());
    System.out.println(annotation.operate());
    System.out.println(annotation.operate());
	}
}