50,504
社区成员
发帖
与我相关
我的任务
分享
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.Date;
public class AnnotationTest {
public static void main(String[] args) throws Exception {
// 通过内省获得 BeanInfo 对象,用于提取属性值
// 后面一个 Object.class 表示,当前继承链截止到 Object 为止,也就是说 Object 的属性不被提取
BeanInfo beanInfo = Introspector.getBeanInfo(Order.class, Object.class);
// 获取属性集
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for(int i = 0; i < pds.length; i++) {
Column column = propertyParse(pds[i]);
System.out.println("property: " + pds[i].getName());
if(column == null) {
System.out.println(" has not been annotated @Column");
continue;
}
// 这里 Column 的两个方法,就是在 @interface Column 中定义的那两个
System.out.println(" @Column name = " + column.name());
System.out.println(" @Column index = " + column.index());
}
}
/**
* 提取属性中 get 或者 set 方法上标注的 @Column 信息
* @param pd
* @return
*/
private static Column propertyParse(PropertyDescriptor pd) {
// 获得属性的 get 方法
Method read = pd.getReadMethod();
// 看看 get 方法上是否标注了 @Column,优先采用 get 方法上的标注
if(read != null && read.isAnnotationPresent(Column.class)) {
return read.getAnnotation(Column.class);
}
// 获得属性的 set 方法
Method write = pd.getWriteMethod();
// 看看 set 方法上是否标注了 @Column
if(write != null && write.isAnnotationPresent(Column.class)) {
return write.getAnnotation(Column.class);
}
// 都没有标注的话返回 null
return null;
}
}
class Order {
private String orderId;
private Date orderTime;
@Column(name = "ORDER_ID")
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public Date getOrderTime() {
return orderTime;
}
@Column(name = "ORDER_TIME", index = 1)
public void setOrderTime(Date orderTime) {
this.orderTime = orderTime;
}
}
//表示运行时有效
@Retention(RetentionPolicy.RUNTIME)
// ElementType.METHOD 表示可以标注于方法上
// ElementType.FIELD 表示可以标注于成员变量上
// 这里的参数是数组,可以写多个
@Target({ ElementType.METHOD })
@interface Column {
String name(); // 没有 default 的话,标注时必须填值
int index() default 0; // 有 default 的话,标注时不填值时使用默认值
}