Java自定义注解实现过程
2017-07-09 18:17
375 查看
步骤
1、创建自定义注解类,并添加校验规则
2、解析自定义注解类并实现校验方法
3、创建测试类并声明自定义注解
4、编写Junit测试类测试结果
运行结果
运行结果
1、创建自定义注解类,并添加校验规则
2、解析自定义注解类并实现校验方法
3、创建测试类并声明自定义注解
4、编写Junit测试类测试结果
自定义注解类
package com.swk.common.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 自定义注解类 * @author fuyuwei * @Retention: 定义注解的保留策略 * @Retention(RetentionPolicy.SOURCE) 注解仅存在于源码中,在class字节码文件中不包含 @Retention(RetentionPolicy.CLASS) 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得, @Retention(RetentionPolicy.RUNTIME) 注解会在class字节码文件中存在,在运行时可以通过反射获取到 @Target 注释类型声明 CONSTRUCTOR 构造方法声明 FIELD 字段声明(包括枚举常量) LOCAL_VARIABLE 局部变量声明 METHOD 方法声明 PACKAGE 包声明 PARAMETER 参数声明 TYPE 类、接口(包括注释类型)或枚举声明 */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE,ElementType.FIELD,ElementType.PARAMETER}) public @interface CustomAnnotation { /** * 是否为空 * @return */ boolean isNull() default false; /** * 最大长度 * @return */ int maxLength() default 8; /** * 字段描述 * @return */ String description() default ""; }
实现自定义注解类规则读取与校验
package com.swk.common.annotation; import java.lang.reflect.Field; import java.util.concurrent.ConcurrentHashMap; import org.springframework.util.StringUtils; import com.swk.common.enums.CommonPostCode; import com.swk.common.exception.PostingException; /** * 解析自定义注解,并完成校验 * @author fuyuwei */ public class AnnotationChecker { private final static ConcurrentHashMap<String,Field[]> fieldsMap = new ConcurrentHashMap<String, Field[]>(); public AnnotationChecker(){ super(); } public static void checkParam(Object object) throws PostingException{ Class<? extends Object> clazz = object.getClass(); Field[] fields = null; if(fieldsMap.containsKey(clazz.getName())){ fields = fieldsMap.get(clazz.getName()); } // getFields:获得某个类的所有的公共(public)的字段,包括父类;getDeclaredFields获得某个类的所有申明的字段,即包括public、private和proteced,但是不包括父类的申明字段 else{ fields = clazz.getDeclaredFields(); fieldsMap.put(clazz.getName(), fields); } for(Field field:fields){ synchronized(field){ field.setAccessible(true); check(field, object); field.setAccessible(false); } } } private static void check(Field field,Object object) throws PostingException{ String description; Object value = null; CustomAnnotation ca = field.getAnnotation(CustomAnnotation.class); try { value = field.get(object); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } if (ca == null) return; // 如果没有标注description默认展示字段名称 description = ca.description().equals("")?field.getName():ca.description(); if(!ca.isNull()){ if(value == null || StringUtils.isEmpty(value.toString().trim())){ throw new PostingException(CommonPostCode.PARAM_LENGTH.getErrorCode(),description+" "+CommonPostCode.PARAM_NULL.getErrorMesage()); } } if(value.toString().length() > ca.maxLength()){ throw new PostingException(CommonPostCode.PARAM_LENGTH.getErrorCode(),description+" "+CommonPostCode.PARAM_LENGTH.getErrorCode()); } } }
创建依赖的其他类
枚举类
package com.swk.common.enums; public enum CommonPostCode { PARAM_NULL(-1,"param required"), PARAM_LENGTH(-2,"param too long"); private int errorCode; private String errorMesage; private CommonPostCode(int errorCode, String errorMesage) { this.errorCode = errorCode; this.errorMesage = errorMesage; } public int getErrorCode() { return errorCode; } public void setErrorCode(int errorCode) { this.errorCode = errorCode; } public String getErrorMesage() { return errorMesage; } public void setErrorMesage(String errorMesage) { this.errorMesage = errorMesage; } }
自定义异常类
package com.swk.common.exception; public class PostingException extends RuntimeException { private static final long serialVersionUID = 5969404579580331293L; private int errorCode; private String errorMessage; public PostingException(int errorCode, String errorMessage) { super(); this.errorCode = errorCode; this.errorMessage = errorMessage; } public int getErrorCode() { return errorCode; } public void setErrorCode(int errorCode) { this.errorCode = errorCode; } public String getErrorMessage() { return errorMessage; } public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; } }
创建声明自定义注解的测试类
package com.swk.request; import com.swk.common.annotation.CustomAnnotation; public class UserInfoRequest { @CustomAnnotation(isNull=false,maxLength=4,description="姓名") private String name; @CustomAnnotation(isNull=false,maxLength=11,description="手机号") private String mobile; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } }
编写Junit测试类
package com.swk.test.annotation; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.sun.istack.internal.logging.Logger; import com.swk.common.annotation.AnnotationChecker; import com.swk.common.exception.PostingException; import com.swk.request.UserInfoRequest; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:spring-mybatis.xml"}) public class AnnotationTest { private Logger logger = Logger.getLogger(AnnotationTest.class); @Test public void testAnnotation(){ UserInfoRequest request = new UserInfoRequest(); try { AnnotationChecker.checkParam(request); } catch (PostingException e) { logger.info(e.getErrorCode()+":"+e.getErrorMessage()); } } }
运行结果
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:spring-mybatis.xml"}) public class AnnotationTest { private Logger logger = Logger.getLogger(AnnotationTest.class); @Test public void testAnnotation(){ UserInfoRequest request = new UserInfoRequest(); request.setName("齐天大圣孙悟空"); try { AnnotationChecker.checkParam(request); } catch (PostingException e) { logger.info(e.getErrorCode()+":"+e.getErrorMessage()); } } }
运行结果
相关文章推荐
- [原创]Java使用反射及自定义注解实现对象差异性比较
- java SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- 利用Spring的AOP编程和JAVA自定义注解,实现Web项目的HTTP请求头域检测
- JAVA自定义注解实现SQL语句自动生成DEMO
- JAVAWEB开发之Servlet3.0新特性的使用以及注解的详细使用和自定义注解的方法、动态代理的使用、利用动态代理实现细粒度的权限控制以及类加载和泛型反射
- java SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- java自定义注解实现前后台参数校验
- Java自定义注解实现Redis自动缓存的方法
- Java自定义注解——简易实现spring @Autowired
- Java 自定义注解实现ORM对象关系映射
- Java 自定义注解实现网络访问重试
- Java自定义注解——简易实现spring @Autowired
- 关于JAVA的Annotation(注解的实现过程)
- java 自定义注解 spring aop 实现注解
- java中实现自定义注解
- java SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- java SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- Java自定义注解的实现
- java自定义注解实现对象到xml配置的转换
- 2017/2/23 Java SpringAOP拦截Service实现日志管理(自定义注解)