本文只简单分析注解的使用,供注解初学者尝试使用,使用过程当中还须要本身增强原理追溯;java
包含(注解是什么,如何自定义注解,注解做用在那里,如何在开发中使用注解)api
一、注解是什么?测试
官方定义:spa
注解(Annotation),也叫元数据。一种代码级别的说明。
what ???? 啥是元数据??代理
元数据:描述数据的数据。(举例:我形容某我的,哪身高,体重,肤色,头发等 就是元数据了)对象
可是,注解是描述什么的呢?(类, 方法, 属性..)blog
常规理解:注解就是对指定对象的额外信息指定和约束,但这个指定和约束必须要有监督者,才真正发挥做用。 开发
好比:get
@Target({ElementType.FIELD, ElementType.METHOD}) // 做用对象(FIELD:属性,METHOD:方法 固然还有其余枚举,) @Retention(RetentionPolicy.RUNTIME) //(运行时生效) public @interface FieldCanNotNull { }
上面就是一个简单入门的注解,在运行的时候,是有效的,可被获取及解析的。
//测试类 public class Person{ @FieldCanNotNull //这个注解就是咸鱼 private String merchangNO; }
可是,这个在没有代码解释的时候,毫无心义。
怎么才能让它变得有意义,有价值?
那就是经过某种方式 ,能够在运行的时候获取到这个对象的 merchangNO 属性信息,而且获取这个属性的元数据。而 @FieldCanNotNull 就是元数据。
想要获取的话,那就须要经过反射的方式,或者当前类的基础信息,并获取当前属性的注解信息。
/** * 属性非空校验 * @param object * @return */ public static boolean isNull4fields(Object object){ if (isNull(object)){ throw NetInException.PARAM_REQUIRED_ERROR.newInstance("object can not be null"); } List<Field> fields = getAllFields(object.getClass(), new ArrayList<>()); //获取全部属性 if (CollectionUtils.isEmpty(fields)){ return false; } Iterator<Field> iterator = fields.iterator(); //获取迭代器 Object fieldVal; while ( iterator.hasNext()) { Field field = iterator.next(); if ( field.isAnnotationPresent(FieldCanNotNull.class)){ //判断当前属性是否有 FieldCanNotNull 注解 fieldVal = invokeGetMethod(field.getName(), "", object); //调用当前属性的get 方法获取属性值 if(isNull(fieldVal)){ //若是当前属性址是空 String errMsg = field.getName() + " can not be null"; //组装信息 抛出异常 throw NetInException.PARAM_REQUIRED_ERROR.newInstance(errMsg, null); } }else{ continue; } } return false; }
真正有意义就是这一段利用反射,获取属性值,比较注解约束内容。而这个方法的逻辑就是赤裸裸的监督者! 监督被约束的对象是否按照约定进行。it
因此: 注解是鱼 , 反射解析是水, 二者相辅相成。
好的! 那么我们进入一个全流程(自定义注解)
一、定义注解(也就是创建法律约束)
二、在将要被约束的对象/方法/属性 上添加注解(法律针对对象)
三、特定的反射功能,获取注解,解析注解并校验 (法律解读,监督者检查是否违背法律)
四、在特定的地方调用反射功能 也就是调用监督者。
开发过程什么状况下使用注解?
一、有校验需求时
二、有约束需求时
三、有隔离了本来业务的非业务功能时 ...
等等,这个感受有点像AOP的思想啊,没错,咱们在使用的过程通常还真的是把这个监督者使用AOP思想来实现。这样就从核心业务上把注解给解析判断喽!
那怎么样呢?还有啥?
既然是AOP那么代理是必然要有的。
因此最终经常使用的就是 , 在代理类中 使用反射 前置处理 解析注解 最后调用目标方法;
例以下面:使用Spring实现AOP 在调用方法以前,进行前置注解解析和处理
前置处理(AOP)
@Aspect public class VerifyAop { /** * 校验参数 * @param joinPoint * @throws Throwable */ public void verifyMethod(JoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); for (Object arg:args){ VerifyUtil.isNull4fields(arg); } } /** * 环绕处理 * @param point * @return * @throws Throwable */ public Object exeMethod(ProceedingJoinPoint point) throws Throwable { return point.proceed(); } }
校验方法(监督者)
public class VerifyUtil { private VerifyUtil(){}; /** * 校验参数为否为空 * @param param * @param paramDesc 参数名 */ public static void validateNotEmptyParam(Object param, String paramDesc){ if (param == null){ throw NetInException.PARAM_REQUIRED_ERROR.newInstance(paramDesc + "为必填项"); } if ((param instanceof Map && MapUtils.isEmpty((Map)param)) || (param.getClass().isArray() && ArrayUtils.getLength(param) ==0) || (param instanceof CollectionUtils && CollectionUtils.isEmpty((Collection)param)) || (param instanceof String && StringUtils.isEmpty(((String)param).trim()))){ throw NetInException.PARAM_VALIDATE_ERROR.newInstance(paramDesc + "不能为空"); } } /** * 判断对象是否为空 * @param object * @return */ public static boolean isNull(Object object){ if (object==null){ return true; }else if (StringUtils.isEmpty(object.toString())){ return true; } return false; }
/** * 属性非空校验 * @param object * @return */ public static boolean isNull4fields(Object object){ if (isNull(object)){ throw NetInException.PARAM_REQUIRED_ERROR.newInstance("object can not be null"); } List<Field> fields = getAllFields(object.getClass(), new ArrayList<>()); //获取全部属性 if (CollectionUtils.isEmpty(fields)){ return false; } Iterator<Field> iterator = fields.iterator(); //获取迭代器 Object fieldVal; while ( iterator.hasNext()) { Field field = iterator.next(); if ( field.isAnnotationPresent(FieldCanNotNull.class)){ //判断当前属性是否有 FieldCanNotNull 注解 fieldVal = invokeGetMethod(field.getName(), "", object); //调用当前属性的get 方法获取属性值 if(isNull(fieldVal)){ //若是当前属性址是空 String errMsg = field.getName() + " can not be null"; //组装信息 抛出异常 throw NetInException.PARAM_REQUIRED_ERROR.newInstance(errMsg, null); } }else{ continue; } } return false; }
/** *获取当前类及当前类的多层父类属性集合 * @param clazz * @param fields * @return */ public static List<Field> getAllFields(Class clazz,List<Field> fields ){ Field[] declaredFields = clazz.getDeclaredFields(); Class superclass = clazz.getSuperclass(); if (superclass == null || "Object".equals(superclass.getSimpleName())){ fields.addAll(Lists.newArrayList(declaredFields)); return fields; }else { List<Field> fieldsList = Arrays.asList(declaredFields); fields.addAll(fieldsList); getAllFields(superclass, fields); } return fields; } /** * 调用指定对象的getXX 方法(用于获取某个对象的某个属性的值) * @param fieldName * @param suffix * @param object * @return */ private static Object invokeGetMethod(String fieldName, String suffix, Object object ) { Method mget = ReflectionUtils.findMethod(object.getClass(), "get" + StringUtils.capitalize(fieldName) + StringUtils.trimToEmpty(suffix)); return ReflectionUtils.invokeMethod(mget, object); } }