java用Annotation注入到成员Bean对象

在使用一些java框架的时候,经常看到一些注解,而且使用注解之后就可以免去一些xml的繁琐配置,本文记录如何通过注解获得成员Bean对象。

一、首先定义Bean

class Person {
private String username;
private int age; public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "Person{" +
"username='" + username + '\'' +
", age=" + age +
'}';
}
}

二、编写和bean一致的注解

// Retention为元注解(注解的注解),这里设置了注解的生命周期为运行时
// 默认情况下,RetentionPolicy为CLASS,字节码注释一般给IDE或者一些工具看的,不能在运行时读取值
// 还有一种为SOURCE,在编译时交给编译器处理,比CLASS时间更早
@Retention(RetentionPolicy.RUNTIME)
@interface InjectPerson {
String username();
int age();
}

三、编写DAO

我们在这里注入对象

class PersonDao {
private Person person; public Person getPerson() {
return person;
} @InjectPerson(username = "Nike", age = 20)
public void setPerson(Person person) {
this.person = person;
}
}

四、利用反射生成对象并读取注解装配对象

public class TestDemo2 {

    public static void main(String[] args) {
try {
// 获取通过反射创建person
PropertyDescriptor descriptor = new PropertyDescriptor("person", PersonDao.class);
Person person = (Person) descriptor.getPropertyType().newInstance(); // 得到person成员对象的setter
Method method = descriptor.getWriteMethod(); // 得到setter的注解
Annotation annotation = method.getAnnotation(InjectPerson.class); // 得到注解的值并装配对象
Method[] methods = annotation.getClass().getMethods();
for (Method m : methods) {
String name = m.getName();
for (Field field : person.getClass().getDeclaredFields()) {
// 匹配对应字段
if (name.equals(field.getName())) {
// 读取annotation中各个属性的值 annotation.age(), 以及annotation.name()
Object value = m.invoke(annotation, null); // 得到setter
PropertyDescriptor attributeDescriptor = new PropertyDescriptor(name, Person.class);
Method setPersonMethod = attributeDescriptor.getWriteMethod(); // 装配
setPersonMethod.invoke(person, value);
}
}
} // 在把装配好的person注入到dao
PersonDao personDao = new PersonDao();
method.invoke(personDao, person); System.out.println(personDao.getPerson()); } catch (IllegalAccessException |
IntrospectionException |
InstantiationException |
InvocationTargetException e) {
e.printStackTrace();
}
}
}

五、小结

总体思想就是:

  1. 得到想要注解的对象
  2. 得到该对象的setter
  3. 读取setter上annotation上的值并注入到对象上
  4. 把装配完之后的对象赋给所有者

本来一直以为注解只是给编译器检查代码用的,没想到利用反射能做这么多事,这种惊叹和博主刚接触C++的宏编程时类似,感觉奇妙无比。

最新文章

  1. IP地址,子网掩码,默认网关,DNS服务器知识详解(转)
  2. js之字符串操作
  3. AppCan接入微信并且进行文字分享
  4. HiKey连接
  5. java配置问题
  6. pb中创建连接webservice对象实例方法
  7. jquery的一些用法
  8. jQuery Ajax 实例 ($.ajax、$.post、$.get)【转载】
  9. 【Android病毒分析报告】 - ZooTiger “集恶意推广、隐私窃取、恶意吸费于一体”
  10. FatMouse and Cheese 动态化搜索
  11. JS中的单引号和双引号
  12. 2019-3-22c# TextBox只允许输入数字,禁用右键粘贴,允许Ctrl+v粘贴数字
  13. 你应该学会的接口调试神器——Postman高级用法
  14. [51Nod1238]最小公倍数之和 V3[杜教筛]
  15. java回顾(项目前期的基本准备)
  16. IllegalStateException: Can not perform this action after onSaveInstanceState
  17. pThreads线程(二) 线程同步--互斥量/锁
  18. Linux 环境部署记录(二) - NFS文件共享
  19. 【算法】Logistic regression (逻辑回归) 概述
  20. KRBTabControl

热门文章

  1. Vagrant box 增加磁盘容量方法
  2. Linux下的用户和用户组,文件权限:chown和chmod
  3. 卡片拖拽(vue拖拽事件)
  4. 使用Django开发简单接口:文章增删改查
  5. Python中文转为拼音
  6. codeforces Educational Codeforces Round 65 (补完)
  7. 网络协议相关面试问题-DNS相关面试问题
  8. Python中json的简单读写操作
  9. libusb_bulk_transfer返回值不是0
  10. 卸载nginx