自定义注解

一、   目的:

自定义注解实现,POJO校验

二、元注解、标准注解

@Target 定义范围

CONSTRUCTOR

用于描述构造器(领盒饭)。

FIELD

用于描述域(领盒饭)。

LOCAL_VARIABLE

用于描述局部变量(领盒饭)。

METHOD

用于描述方法。

PACKAGE

用于描述包(领盒饭)。

PARAMETER

用于描述参数。

TYPE

用于描述类或接口(甚至 enum )。

@Retention 运行时效

取值

描述

SOURCE

在源文件中有效(即源文件保留,领盒饭)。

CLASS

 class 文件中有效(即 class 保留,领盒饭)。

RUNTIME

在运行时有效(即运行时保留)。

@Documented 在默认的情况下javadoc命令不会将我们的annotation生成再doc中去的,所以使用该标记就是告诉 jdk让它也将annotation生成到doc中去

@Inherited 子类继承注解

自动定义注解,例如

public @interface Complexity {
    public enum Level {
        VERY_SIMEPLE, SIMPLE, MEDIUM, COMPLEX, VERY_COMPLEX
    } default @Complexity.MEDIUM
}
@Target(ElementType.FIELD)  //作用域
@Retention(RetentionPolicy.RUNTIME) //运行时效
@Documented  
@Inherited //继承注解
public @interface IsEmptyAnnotation {
    
    public boolean isEmpty() default true;
    
    public String message() default "字段不能为空";
}

三、注解处理器

处理器的代码虽然写完了,但是这还没完呢,剩下还有非常重要的步骤,那就是添加注册信息。因为注解处理器是属于javac的一个平台级的功能,所以我们的使用方式是将代码打包成jar的形式,这样就可以在其他第三方项目当中使用了。而在打包jar之前,则要在项目中添加注册信息

 

四、实现POJO的校验

User

public class User {
    
    @IsEmptyAnnotation
    public String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

@IsEmptyAnnotation 

@Target(ElementType.FIELD)  //作用域
@Retention(RetentionPolicy.RUNTIME) //运行时效
@Documented  
@Inherited //继承注解
public @interface IsEmptyAnnotation {
    
    public boolean isEmpty() default true;
    
    public String message() default "字段不能为空";
}
AnnotationDealUtil  利用反射的机制对注解进行校验
public class AnnotationDealUtil {
     private static Logger log = Logger.getAnonymousLogger();  
     
      @SuppressWarnings("unchecked")  
        public static Map<String, Object> validate(Object bean) {  
            Map<String, Object> result = new HashMap<String, Object>();  
            result.put("message", "验证通过");  
            result.put("result", true);  
            Class<?> cls = bean.getClass();  
              
            // 检测field是否存在  
            try {  
                // 获取实体字段集合  
                Field[] fields = cls.getDeclaredFields();  
                for (Field f : fields) {  
                    // 通过反射获取该属性对应的值  
                    f.setAccessible(true);  
                    // 获取字段值  
                    Object value = f.get(bean);  
                    // 获取字段上的注解集合  
                    Annotation[] arrayAno = f.getAnnotations();  
                    for (Annotation annotation : arrayAno) {  
                        // 获取注解类型(注解类的Class)  
                        Class<?> clazz = annotation.annotationType();  
                        // 获取注解类中的方法集合  
                        Method[] methodArray = clazz.getDeclaredMethods();  
                        for (Method method : methodArray) {  
                            // 获取方法名  
                            String methodName = method.getName();  
                            // 过滤错误提示方法的调用  
                            if(methodName.equals("message")) {  
                                continue;  
                            }  
                            // 初始化注解验证的方法处理类 (我的处理方法卸载本类中)  
                            Object obj = AnnotationDealUtil.class.newInstance();  
                            // 获取方法  
                            try {  
                                // 根据方法名获取该方法  
                                Method m = obj.getClass().getDeclaredMethod(methodName, Object.class, Field.class);  
                                // 调用该方法  
                                result = (Map<String, Object>)m.invoke(obj, value, f);  
                                /* 验证结果 有一处失败则退出 */  
                                if(result.get("result").equals(false)) {  
                                    return result;  
                                }  
                            } catch (Exception e) {  
                                e.printStackTrace();  
                                log.info("找不到该方法:"+methodName);  
                            }  
                        }  
                    }  
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
                log.info("验证出错");  
            }  
            return result;  
        }  
    
    public Map<String, Object> isEmpty(Object value, Field field) {  
        Map<String, Object> validateResult = new HashMap<String, Object>();  
        IsEmptyAnnotation annotation = field.getAnnotation(IsEmptyAnnotation.class);  
        if(value == null || value.equals("")) {  
            validateResult.put("message", field.getName() + annotation.message());  
            validateResult.put("result", false);  
        } else {  
            validateResult.put("message", "验证通过");  
            validateResult.put("result", true);  
        }  
        return validateResult;  
    }  
}

main

    public static void main(String[] args) {
        User advertise = new User();  
        advertise.setName("a");  
        System.out.println(AnnotationDealUtil.validate(advertise));
    }

 


 

参考链接:

粗略的讲解了,AOP,注解,自定义注解,拦截器 的基本知识  http://www.cnblogs.com/shipengzhi/articles/2716004.html

注解实现的校验,一般都是由反射实现  http://blog.csdn.net/bao19901210/article/details/17201173/

posted @ 2017-11-29 19:17  litblack  阅读(392)  评论(0编辑  收藏  举报