JAVA自定义注解

现有一个特殊JavaBean,里面有4个字段,分别是

id,type,title,content。

假设还有一个UserInfoVO,里面有

id,userName,nickName,telphone,mail,address

等字段信息,

想要将UserInfoVO里面的id set到JavaBean里面的id,将userName,或者nickName set到title,将telphone,mail,address等信息set到content,现在只有这一个UserInfoVO所以你可以这样写:

setId(UserInfoVO.getId());

setTitle(UserInfoVO.getTitle());

setContent(UserInfoVO.getContent());

但是如果有多个这样的VO呢,是不是要为每个类写一遍呢?显然不是的,我们只是不知道每个VO中哪个字段要set到id中,哪个字段要set到title中,现在我们定义如下注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(value={ElementType.TYPE})
@Inherited
public @interface VoAnnotion {

}

@Retention(RetentionPolicy.RUNTIME)
@Target(value = { ElementType.METHOD })
@Inherited
public @interface VoField {
    String name();
    String value();  
}

@VoAnnotion
public class UserInfoVO {
    private String id;
    private String name;
    private String tel;
    private String email;
    private String address;

    @VoField(name = "id" , value ="id")
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    @VoField(name = "title" , value ="name")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @VoField(name = "content" , value ="tel")
    public String getTel() {
        return tel;
    }
    public void setTel(String tel) {
        this.tel = tel;
    }

    @VoField(name = "content" , value ="email")
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
}

我们想把什么字段set进id就在那个字段的get方法上写上注解@VoField(name = “id”, value=”id”)。这里要解释一下注解的作用:注解其实是给某个类或某个方法或某个字段加上标签,比如说:给一个方法插上一个的标签,那么在程序中用到这个方法时就能知道这是我当初定义过的,要怎么使用就看自己的业务了。name = “id”,当我以后用到这个方法时,我就知道这个方法的值是要被set进id中的。

注解中:

ElementType.TYPE:能修饰类、接口或枚举类型
ElementType.FIELD:能修饰成员变量
ElementType.METHOD:能修饰方法
ElementType.PARAMETER:能修饰参数
ElementType.CONSTRUCTOR:能修饰构造器
ElementType.LOCAL_VARIABLE:能修饰局部变量
ElementType.ANNOTATION_TYPE:能修饰注解
ElementType.PACKAGE:能修饰包


/**
 * 解析带注解的vo,组装luceneExtendVO
 * @author JiaJiCheng
 *
 */
public class AssemblyLuceneVOUtil {
    private static final Log LOG = LogFactory.getLog(AssemblyLuceneVOUtil.class);

    /**
     * 将VO转换成BeanLuceneExtend对象
     * @param obj
     * @return
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static BeanLuceneExtend  objToLuceneExtend(Object obj)
    {
        try
        {
            if(obj == null)
            {
                return null;
            }

            StringBuilder id = new StringBuilder();
            StringBuilder type = new StringBuilder();
            StringBuilder title = new StringBuilder();
            StringBuilder content = new StringBuilder();

            // 得到类的抽象数据类型
            Class clazz = obj.getClass();
            // 判断是否是自己定义的注解类
            if(clazz.isAnnotationPresent(VoAnnotion.class))
            {
                BeanInfo info = Introspector.getBeanInfo(clazz);
                PropertyDescriptor[] props = info.getPropertyDescriptors();
                for(PropertyDescriptor prop : props)
                {
                    // 获取类中的get方法
                    Method method = prop.getReadMethod();
                    String name = prop.getName();
                    if (method == null || "class".equals(name)) {
                        continue;
                    }
                    if (!method.isAccessible()) {
                        method.setAccessible(true);
                    }
                    // invoke方法为  执行get方法,obj是依赖的类,((Object[]) null)是方法的参数。
                    Object value = method.invoke(obj, (Object[]) null);
                    if (value != null && method.isAnnotationPresent(VoField.class)) {
                    // 拿到当前get方法的注解
                        VoField annotionName = method.getAnnotation(VoField.class);
                        makeParamByAnnotion(annotionName, value, id, type, title, content);
                    }
                }
                return makeParam(id, type, title, content);
            }
        }catch(Exception e)
        {
            LOG.error("构造BeanLunceneExtend对象失败 " + e.toString());
        }
        return null;
    }

    private static BeanLuceneExtend makeParam(StringBuilder id, StringBuilder type, StringBuilder title, StringBuilder content)
    {
        BeanLuceneExtend extend = new BeanLuceneExtend();
        extend.setId(id.toString());
        extend.setType(type.toString());
        extend.setContent(content.deleteCharAt(content.length()-1).toString());
        extend.setTitle(title.toString());
        return extend;
    }

    /**
     * 根据注解读取内容,组装内容
     * @param voField 注解vo
     * @param value get方法的值
     * @return
     */
    private static void makeParamByAnnotion(VoField voField, Object value, StringBuilder id, StringBuilder type, StringBuilder title, StringBuilder content)
    {
        if(value == null || "".equals(value) || voField == null)
        {
            return;
        }
        //字段是id
        if(voField.name().toUpperCase().equals(LuceneExtendFieldEnum.ID.toString()))
        {
            LOG.info("****start to assemble id****");
            if(id == null || id.length() == 0)
            {
                id.append(voField.value() + ":");
            }
            id.append(value);
        }
        else if(voField.name().toUpperCase().equals(LuceneExtendFieldEnum.TYPE.toString()))
        {
            LOG.info("****start to assemble type****");
            if(type == null || type.length() == 0)
            {
                type.append(voField.value() + ":");
            }
            type.append(value);
        }
        else if(voField.name().toUpperCase().equals(LuceneExtendFieldEnum.TITLE.toString()))
        {
            LOG.info("****start to assemble title****");
            if(title == null || title.length() == 0)
            {
                title.append(voField.value() + ":");
            }
            title.append(value);
            if(content == null || content.length() == 0)
            {
                content.append(voField.value() + ":");
            }
            content.append(value).append(",");
        }
        else if(voField.name().toUpperCase().equals(LuceneExtendFieldEnum.CONTENT.toString()))
        {
            LOG.info("****start to assemble content****");
            if(content == null || content.length() == 0)
            {
                content.append(voField.value() + ":");
            }
            content.append(value).append(",");
        }
    }

}

以上代码是具体的使用业务。这里使用的JAVA反射机制,动态的调用get方法,拿到值。

你可能感兴趣的:(JAVA基础)