解析字段上的注解并为该字段注入一个对象

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;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                '}';
    }
}

 

3,创建一个LoginDAO

package 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}
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值