解析字段上的注解并为该字段注入一个对象
2016-05-22 00:54
441 查看
1,创建一个注解类package com.sunyb.annotation;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;/*** 用户实体注解类* @author sunyb* @since 2016-05-21* @version 1.0*///运行时注解@Retention(RetentionPolicy.RUNTIME)public @interface Inject {String name();String password();int age();}2,创建一个User实体类<pre name="code" class="java">package com.sunyb.annotation;/*** 用户实体类* @author sunyb* @since 2016-05-21* @version 1.0*/public class User {private String name;private String password;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", password='" + password + '\'' +", age=" + age +'}';}}3,创建一个LoginDAOpackage com.sunyb.annotation;/*** 用户登录DAO* @author sunyb* @since 2016-05-21* @version 1.0*/public class LoginDao {@Inject(name="zhangsan", password="123", age=18)private User user;public void login(){System.out.println("Current user:" + user);}}4,创建一个LoginDao工厂类
package com.sunyb.annotation; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * LoginDao工厂类 * @author sunyb * @since 2016-05-21 * @version 1.0 */ public class LoginDaoFactory { /** * 创建LoginDao对象 * @return */ public static LoginDao createLoginDao(){ // 1,首先创建一个LoginDao对象 LoginDao dao = new LoginDao(); //2,然后反射出LoginDao对象上所有的字段 Field[] fields = dao.getClass().getDeclaredFields(); //3,遍历得到每个Field if(fields != null){ for(Field field : fields){ //设置暴力访问 field.setAccessible(true); //获取到该字段上指定的注解:Inject //@Inject(name="zhangsan", password="123", age=18) Inject inject = field.getAnnotation(Inject.class); //如果当前字段上没有Inject注解,则获取到的为null,继续下一次循环 if (inject == null){ continue; } //如果程序走到这里,说明已经找到Inject注解 //使用注解上的信息创建一个user对象,并赋值给LoginDao //为了通用,我们不直接创建user,而是使用反射技术实例化对象 //例如:private User user; //field.getType()的返回值为Class,可以使用Class实例化具体的对象 try { Object obj = field.getType().newInstance(); //使用注解的信息,给obj对象赋值 injectToObject(inject, obj); //使用反射,调用Loginao的set方法,并把obj对象设置进去 field.set(dao, obj); } catch (Exception e) { throw new RuntimeException(e); } } } return dao; } /** * 使用inject这个注解上的信息,给obj对象赋值 * @param inject 注解 * @param obj 对象 */ private static void injectToObject(Inject inject, Object obj) { //1,首先得到inject这个注解上所有的方法 //@Inject(name="zhangsan", password="123", age=18) Method[] methods = inject.getClass().getMethods(); //循环遍历出每个方法 for(Method method : methods){ //获取到方法名称,例如:name() , age() String methodName = method.getName(); //使用内省技术获取到obj对象上与方法名称相同的属性 try { PropertyDescriptor pd = new PropertyDescriptor(methodName, obj.getClass()); //如果代码走到这里,说明已经找到了obj中的属性名称和注解上的方法相同 //例如本例中:Inject注解有一个name()方法,而User对象中有一个name属性 //开始使用反射技术调用inject这个注解上的方法,例如调用String name()这个方法 //参数为空所以传null,返回值为String,其实是注解上该方法的返回值 Object value = method.invoke(inject, null); //把得到的值赋值给具体的对象 //首先通过内省,得到对象的写方法 Method setMethod = pd.getWriteMethod(); //最后,完成setter方法的调用,即完成赋值 setMethod.invoke(obj, value); } catch (Exception e) { //如果发生异常,说明该注解上的这个方法,在obj对象中没有与之名称相同的属性,则继续循环 continue; } } } }
5,测试程序:
<pre name="code" class="java"> LoginDao dao = LoginDaoFactory.createLoginDao();dao.login();6,运行结果如下:
Current user:User{name='zhangsan', password='123', age=18}
相关文章推荐
- Android中的按钮事件
- php几种运行模式总结
- 为什么国外程序员爱用苹果 Mac 电脑?
- C++作业6
- OGG-00455问题解决
- 为什么国外程序员爱用苹果 Mac 电脑?
- 计算机专业-世界大学学术排名,QS排名,U.S.NEWS排名
- Android SQLite 数据库存储
- Android打造ListView万能适配器
- POJ3280-Cheapest Palindrome
- 计算机专业-世界大学学术排名,QS排名,U.S.NEWS排名
- 4.css度量单位
- centos6.5 ifconfig不显示eth0地址
- OGG-00850解决
- CustomProgressDialog
- Spring-data-redis配置及使用示例
- elasticsearch 使用事项
- Android Studio 中build.gradle文件的详细解析
- 树莓派3-如何打开蓝牙
- iOS 3D Touch 实现UITableViewCell 预览