在搭建系统时,我们经常需要定义很多错误类,包括错误码和错误信息。大多数情况下我们都用最传统的方式来做,比如先定义一组错误code,然后再定义一组错误信息,错误信息放在properties文件或者数据库中,系统启动时加载到内存,放在map中和错误code一一对应,使用时通过错误code获取错误信息返回给用户。 后来JAVA出现了自定义Annotation,这就给我们提供了一种更优雅的方法来管理错误信息类,下面写了一个小DEMO,大家有兴趣的话可以参考下。 JAVA自定义Annotation的用处非常广泛,尤其是在框架开发过程中,以后慢慢记录。 首先定义一个用于错误码定义类的Annotation package errorAno; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface ErrorDefineClass { String value() default "error message description"; } 这个错误码定义类的Annotation的ElementType.TYPE代表其可以作用在类或者接口上,具体可以点进去看看,各种类型有不同的用途。 再定义一个用于错误码属性的Annotation package errorAno; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ErrorDefinition { String value(); } 这个错误码属性的Annotation的ElementType.FIELD代表其是作用在类属性上的注解。 再定义一个错误码类的加载和解析类,或者说构建错误码管理的全局上下文环境 package errorAno; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; public class ErrorContext { public final static int SUCCESS = 0; static private Map<Integer, String> errorMap; static { errorMap = new HashMap<Integer, String>(); ErrorContext.errorMap.put(0, "Business successed!"); } /* *return the preloaded error message without exception */ public static String errnoExplain(int errno) { String explain = errorMap.get(errno); String backup = String.valueOf(errno); return explain != null ? explain : backup; } /* *return unloaded error message without exception */ public static String errnoExplain(int errno, String explain) { if (errorMap.containsKey(errno)) { return errorMap.get(errno); } else { String backup = String.valueOf(errno); return explain != null ? explain : backup; } } /* * analyzed the error class and load them in to memory * */ protected static void proxyExplain(Class<? extends ErrorContext> define) { //make sure the error def class extends ErrorContext if (define != null && define != ErrorContext.class) { final String dname = define.getName(); //make sure the error class is Annotated by ErrorDefineClass if (define.isAnnotationPresent(ErrorDefineClass.class)) { Class<ErrorDefinition> defClazz = ErrorDefinition.class; //analyze the error fields for (Field field : define.getDeclaredFields()) { //make sure the fields is Annotated by ErrorDefinition if (field.isAnnotationPresent(defClazz)) { //make sure the fields is modified by public if (Modifier.isPublic(field.getModifiers())) { try { ErrorDefinition entry = null; int errno = field.getInt(null); entry = field.getAnnotation(defClazz); ErrorContext.errorMap.put(errno, entry.value()); System.out.println("analyzed error message successed:" + entry.value()); } catch (Exception e) { System.out.println("analyze error message exception"); } } } } } } } } 具体详情可以看看代码里的注释,其主要作用就是在系统启动时加载所有的错误码定义类和属性,然后在使用时可以直接调用找到相应的错误码。 最后来看看如何融合到你的系统中去 package errorAno; @ErrorDefineClass public class BusinessError extends ErrorContext{ /* * preload this error Class when system is startup * */ static { ErrorContext.proxyExplain(BusinessError.class); } @ErrorDefinition("The action code is incorrect") final public static int ERR_ACTION_CODE = 1; @ErrorDefinition("The parameters is incorrect") final public static int ERR_PARAMETER = 2; public static void main(String[] args) { System.out.println(ErrorContext.SUCCESS); System.out.println(ErrorContext.errnoExplain(1)); System.out.println(ErrorContext.errnoExplain(2)); } } 这就是一个你需要在系统中定义的错误码类,在系统启动时这个类会被自动加载,这种Annotation的用法就不需要以往那种循环加载map或者各种数据结构的操作了,只需要按照Annotation的标准来写,系统就会自动加载你需要的内容。来看看测试结果 错误码的管理可以是在数据库中,也可以是在properties中,没有好坏之分,只是根据不同的系统和使用场景做不同的选择,这里只是用错误码管理为例,简要介绍一下JAVA自定义Annotation的使用,供大家参考。 文章导航 Based on Java NIO Socket, implement a customized http server similar to Tomcat, and develop Tomcat by yourself (2) Use JAVA Annotation to construct error parsing class and definition class-Practical application of Java Annotation(1)